From 14907047a3ea109b752412f0a417573275d58297 Mon Sep 17 00:00:00 2001 From: Sean Yang Date: Tue, 10 Dec 2024 10:22:09 -0800 Subject: [PATCH 1/2] add additional BaseFedJob layer --- docs/programming_guide/fed_job_api.rst | 2 +- .../nvflare_lightning_getting_started.ipynb | 8 +- .../pt/nvflare_pt_getting_started.ipynb | 8 +- .../tf/nvflare_tf_getting_started.ipynb | 8 +- nvflare/app_opt/pt/job_config/base_fed_job.py | 31 ++---- nvflare/app_opt/pt/job_config/fed_avg.py | 4 +- .../app_opt/pt/job_config/fed_sag_mlflow.py | 4 +- nvflare/app_opt/tf/job_config/base_fed_job.py | 31 ++---- nvflare/app_opt/tf/job_config/fed_avg.py | 4 +- nvflare/job_config/base_fed_job.py | 103 ++++++++++++++++++ web/src/components/code.astro | 24 ++-- 11 files changed, 148 insertions(+), 79 deletions(-) create mode 100644 nvflare/job_config/base_fed_job.py diff --git a/docs/programming_guide/fed_job_api.rst b/docs/programming_guide/fed_job_api.rst index 8f9e3cec01..0474b9dbc2 100644 --- a/docs/programming_guide/fed_job_api.rst +++ b/docs/programming_guide/fed_job_api.rst @@ -366,7 +366,7 @@ The FedAvgJob automatically adds the FedAvg controller, PTFileModelPersistor and For more examples of job patterns, see: -* :class:`BaseFedJob` +* :class:`BaseFedJob` * :class:`FedAvgJob` (pytorch) * :class:`FedAvgJob` (tensorflow) * :class:`CCWFJob` diff --git a/examples/getting_started/pt/nvflare_lightning_getting_started.ipynb b/examples/getting_started/pt/nvflare_lightning_getting_started.ipynb index 6f26be3100..fa91c994b7 100644 --- a/examples/getting_started/pt/nvflare_lightning_getting_started.ipynb +++ b/examples/getting_started/pt/nvflare_lightning_getting_started.ipynb @@ -321,8 +321,8 @@ "#### 2. Define a FedJob\n", "The `FedJob` is used to define how controllers and executors are placed within a federated job using the `to(object, target)` routine.\n", "\n", - "Here we use a PyTorch `BaseFedJob`, where we can define the job name and the initial global model.\n", - "The `BaseFedJob` automatically configures components for model persistence, model selection, and TensorBoard streaming for convenience." + "Here we use a PyTorch `PTBaseFedJob`, where we can define the job name and the initial global model.\n", + "The `PTBaseFedJob` automatically configures components for model persistence, model selection, and TensorBoard streaming for convenience." ] }, { @@ -335,10 +335,10 @@ "from src.lit_net import LitNet\n", "\n", "from nvflare.app_common.workflows.fedavg import FedAvg\n", - "from nvflare.app_opt.pt.job_config.base_fed_job import BaseFedJob\n", + "from nvflare.app_opt.pt.job_config.base_fed_job import PTBaseFedJob\n", "from nvflare.job_config.script_runner import ScriptRunner\n", "\n", - "job = BaseFedJob(\n", + "job = PTBaseFedJob(\n", " name=\"cifar10_lightning_fedavg\",\n", " initial_model=LitNet(),\n", ")" diff --git a/examples/getting_started/pt/nvflare_pt_getting_started.ipynb b/examples/getting_started/pt/nvflare_pt_getting_started.ipynb index 79e1b99259..e6c474b4fd 100644 --- a/examples/getting_started/pt/nvflare_pt_getting_started.ipynb +++ b/examples/getting_started/pt/nvflare_pt_getting_started.ipynb @@ -263,8 +263,8 @@ "#### 2. Define a FedJob\n", "The `FedJob` is used to define how controllers and executors are placed within a federated job using the `to(object, target)` routine.\n", "\n", - "Here we use a PyTorch `BaseFedJob`, where we can define the job name and the initial global model.\n", - "The `BaseFedJob` automatically configures components for model persistence, model selection, and TensorBoard streaming for convenience." + "Here we use a PyTorch `PTBaseFedJob`, where we can define the job name and the initial global model.\n", + "The `PTBaseFedJob` automatically configures components for model persistence, model selection, and TensorBoard streaming for convenience." ] }, { @@ -277,10 +277,10 @@ "from src.net import Net\n", "\n", "from nvflare.app_common.workflows.fedavg import FedAvg\n", - "from nvflare.app_opt.pt.job_config.base_fed_job import BaseFedJob\n", + "from nvflare.app_opt.pt.job_config.base_fed_job import PTBaseFedJob\n", "from nvflare.job_config.script_runner import ScriptRunner\n", "\n", - "job = BaseFedJob(\n", + "job = PTBaseFedJob(\n", " name=\"cifar10_pt_fedavg\",\n", " initial_model=Net(),\n", ")" diff --git a/examples/getting_started/tf/nvflare_tf_getting_started.ipynb b/examples/getting_started/tf/nvflare_tf_getting_started.ipynb index 61afb4f870..9abafe0de2 100644 --- a/examples/getting_started/tf/nvflare_tf_getting_started.ipynb +++ b/examples/getting_started/tf/nvflare_tf_getting_started.ipynb @@ -253,8 +253,8 @@ "#### 2. Define a FedJob\n", "The `FedJob` is used to define how controllers and executors are placed within a federated job using the `to(object, target)` routine.\n", "\n", - "Here we use a TensorFlow `BaseFedJob`, where we can define the job name and the initial global model.\n", - "The `BaseFedJob` automatically configures components for model persistence, model selection, and TensorBoard streaming for convenience." + "Here we use a TensorFlow `TFBaseFedJob`, where we can define the job name and the initial global model.\n", + "The `TFBaseFedJob` automatically configures components for model persistence, model selection, and TensorBoard streaming for convenience." ] }, { @@ -267,10 +267,10 @@ "from src.tf_net import TFNet\n", "\n", "from nvflare.app_common.workflows.fedavg import FedAvg\n", - "from nvflare.app_opt.tf.job_config.base_fed_job import BaseFedJob\n", + "from nvflare.app_opt.tf.job_config.base_fed_job import TFBaseFedJob\n", "from nvflare.job_config.script_runner import FrameworkType, ScriptRunner\n", "\n", - "job = BaseFedJob(\n", + "job = TFBaseFedJob(\n", " name=\"cifar10_tf_fedavg\",\n", " initial_model=TFNet(),\n", ")" diff --git a/nvflare/app_opt/pt/job_config/base_fed_job.py b/nvflare/app_opt/pt/job_config/base_fed_job.py index 0225064967..dbc2d0a293 100644 --- a/nvflare/app_opt/pt/job_config/base_fed_job.py +++ b/nvflare/app_opt/pt/job_config/base_fed_job.py @@ -18,17 +18,17 @@ from nvflare.app_common.abstract.model_locator import ModelLocator from nvflare.app_common.abstract.model_persistor import ModelPersistor -from nvflare.app_common.tracking.tracker_types import ANALYTIC_EVENT_TYPE from nvflare.app_common.widgets.convert_to_fed_event import ConvertToFedEvent from nvflare.app_common.widgets.intime_model_selector import IntimeModelSelector from nvflare.app_common.widgets.streaming import AnalyticsReceiver from nvflare.app_common.widgets.validation_json_generator import ValidationJsonGenerator from nvflare.app_opt.pt.job_config.model import PTModel from nvflare.app_opt.tracking.tb.tb_receiver import TBAnalyticsReceiver -from nvflare.job_config.api import FedJob, validate_object_for_job +from nvflare.job_config.api import validate_object_for_job +from nvflare.job_config.base_fed_job import BaseFedJob -class BaseFedJob(FedJob): +class PTBaseFedJob(BaseFedJob): def __init__( self, initial_model: nn.Module = None, @@ -72,29 +72,15 @@ def __init__( name=name, min_clients=min_clients, mandatory_clients=mandatory_clients, + key_metric=key_metric, + validation_json_generator=validation_json_generator, + intime_model_selector=intime_model_selector, + convert_to_fed_event=convert_to_fed_event, ) self.initial_model = initial_model self.comp_ids = {} - if validation_json_generator: - validate_object_for_job("validation_json_generator", validation_json_generator, ValidationJsonGenerator) - else: - validation_json_generator = ValidationJsonGenerator() - self.to_server(id="json_generator", obj=validation_json_generator) - - if intime_model_selector: - validate_object_for_job("intime_model_selector", intime_model_selector, IntimeModelSelector) - self.to_server(id="model_selector", obj=intime_model_selector) - elif key_metric: - self.to_server(id="model_selector", obj=IntimeModelSelector(key_metric=key_metric)) - - if convert_to_fed_event: - validate_object_for_job("convert_to_fed_event", convert_to_fed_event, ConvertToFedEvent) - else: - convert_to_fed_event = ConvertToFedEvent(events_to_convert=[ANALYTIC_EVENT_TYPE]) - self.convert_to_fed_event = convert_to_fed_event - if analytics_receiver: validate_object_for_job("analytics_receiver", analytics_receiver, AnalyticsReceiver) else: @@ -109,6 +95,3 @@ def __init__( self.comp_ids.update( self.to_server(PTModel(model=initial_model, persistor=model_persistor, locator=model_locator)) ) - - def set_up_client(self, target: str): - self.to(id="event_to_fed", obj=self.convert_to_fed_event, target=target) diff --git a/nvflare/app_opt/pt/job_config/fed_avg.py b/nvflare/app_opt/pt/job_config/fed_avg.py index 58f10e27a5..f0544aa45c 100644 --- a/nvflare/app_opt/pt/job_config/fed_avg.py +++ b/nvflare/app_opt/pt/job_config/fed_avg.py @@ -16,10 +16,10 @@ import torch.nn as nn from nvflare.app_common.workflows.fedavg import FedAvg -from nvflare.app_opt.pt.job_config.base_fed_job import BaseFedJob +from nvflare.app_opt.pt.job_config.base_fed_job import PTBaseFedJob -class FedAvgJob(BaseFedJob): +class FedAvgJob(PTBaseFedJob): def __init__( self, initial_model: nn.Module, diff --git a/nvflare/app_opt/pt/job_config/fed_sag_mlflow.py b/nvflare/app_opt/pt/job_config/fed_sag_mlflow.py index 131ad11a2f..d6f707d4db 100644 --- a/nvflare/app_opt/pt/job_config/fed_sag_mlflow.py +++ b/nvflare/app_opt/pt/job_config/fed_sag_mlflow.py @@ -19,12 +19,12 @@ from nvflare.app_common.aggregators import InTimeAccumulateWeightedAggregator from nvflare.app_common.shareablegenerators import FullModelShareableGenerator from nvflare.app_common.workflows.scatter_and_gather import ScatterAndGather -from nvflare.app_opt.pt.job_config.base_fed_job import BaseFedJob +from nvflare.app_opt.pt.job_config.base_fed_job import PTBaseFedJob from nvflare.app_opt.tracking.mlflow.mlflow_receiver import MLflowReceiver from nvflare.app_opt.tracking.mlflow.mlflow_writer import MLflowWriter -class SAGMLFlowJob(BaseFedJob): +class SAGMLFlowJob(PTBaseFedJob): def __init__( self, initial_model: nn.Module, diff --git a/nvflare/app_opt/tf/job_config/base_fed_job.py b/nvflare/app_opt/tf/job_config/base_fed_job.py index bf77cd1092..51cab16914 100644 --- a/nvflare/app_opt/tf/job_config/base_fed_job.py +++ b/nvflare/app_opt/tf/job_config/base_fed_job.py @@ -17,17 +17,17 @@ import tensorflow as tf from nvflare.app_common.abstract.model_persistor import ModelPersistor -from nvflare.app_common.tracking.tracker_types import ANALYTIC_EVENT_TYPE from nvflare.app_common.widgets.convert_to_fed_event import ConvertToFedEvent from nvflare.app_common.widgets.intime_model_selector import IntimeModelSelector from nvflare.app_common.widgets.streaming import AnalyticsReceiver from nvflare.app_common.widgets.validation_json_generator import ValidationJsonGenerator from nvflare.app_opt.tf.job_config.model import TFModel from nvflare.app_opt.tracking.tb.tb_receiver import TBAnalyticsReceiver -from nvflare.job_config.api import FedJob, validate_object_for_job +from nvflare.job_config.api import validate_object_for_job +from nvflare.job_config.base_fed_job import BaseFedJob -class BaseFedJob(FedJob): +class TFBaseFedJob(BaseFedJob): def __init__( self, initial_model: tf.keras.Model = None, @@ -69,29 +69,15 @@ def __init__( name=name, min_clients=min_clients, mandatory_clients=mandatory_clients, + key_metric=key_metric, + validation_json_generator=validation_json_generator, + intime_model_selector=intime_model_selector, + convert_to_fed_event=convert_to_fed_event, ) self.initial_model = initial_model self.comp_ids = {} - if validation_json_generator: - validate_object_for_job("validation_json_generator", validation_json_generator, ValidationJsonGenerator) - else: - validation_json_generator = ValidationJsonGenerator() - self.to_server(id="json_generator", obj=validation_json_generator) - - if intime_model_selector: - validate_object_for_job("intime_model_selector", intime_model_selector, IntimeModelSelector) - self.to_server(id="model_selector", obj=intime_model_selector) - elif key_metric: - self.to_server(id="model_selector", obj=IntimeModelSelector(key_metric=key_metric)) - - if convert_to_fed_event: - validate_object_for_job("convert_to_fed_event", convert_to_fed_event, ConvertToFedEvent) - else: - convert_to_fed_event = ConvertToFedEvent(events_to_convert=[ANALYTIC_EVENT_TYPE]) - self.convert_to_fed_event = convert_to_fed_event - if analytics_receiver: validate_object_for_job("analytics_receiver", analytics_receiver, AnalyticsReceiver) else: @@ -104,6 +90,3 @@ def __init__( if initial_model: self.comp_ids["persistor_id"] = self.to_server(TFModel(model=initial_model, persistor=model_persistor)) - - def set_up_client(self, target: str): - self.to(id="event_to_fed", obj=self.convert_to_fed_event, target=target) diff --git a/nvflare/app_opt/tf/job_config/fed_avg.py b/nvflare/app_opt/tf/job_config/fed_avg.py index e25d87f574..7449e0f583 100644 --- a/nvflare/app_opt/tf/job_config/fed_avg.py +++ b/nvflare/app_opt/tf/job_config/fed_avg.py @@ -16,10 +16,10 @@ import tensorflow as tf from nvflare.app_common.workflows.fedavg import FedAvg -from nvflare.app_opt.tf.job_config.base_fed_job import BaseFedJob +from nvflare.app_opt.tf.job_config.base_fed_job import TFBaseFedJob -class FedAvgJob(BaseFedJob): +class FedAvgJob(TFBaseFedJob): def __init__( self, initial_model: tf.keras.Model, diff --git a/nvflare/job_config/base_fed_job.py b/nvflare/job_config/base_fed_job.py new file mode 100644 index 0000000000..c1dd26f543 --- /dev/null +++ b/nvflare/job_config/base_fed_job.py @@ -0,0 +1,103 @@ +# Copyright (c) 2024, NVIDIA CORPORATION. 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. + +from typing import List, Optional + +from nvflare.app_common.abstract.model_locator import ModelLocator +from nvflare.app_common.abstract.model_persistor import ModelPersistor +from nvflare.app_common.tracking.tracker_types import ANALYTIC_EVENT_TYPE +from nvflare.app_common.widgets.convert_to_fed_event import ConvertToFedEvent +from nvflare.app_common.widgets.intime_model_selector import IntimeModelSelector +from nvflare.app_common.widgets.streaming import AnalyticsReceiver +from nvflare.app_common.widgets.validation_json_generator import ValidationJsonGenerator +from nvflare.job_config.api import FedJob, validate_object_for_job + + +class BaseFedJob(FedJob): + def __init__( + self, + name: str = "fed_job", + min_clients: int = 1, + mandatory_clients: Optional[List[str]] = None, + key_metric: str = "accuracy", + validation_json_generator: Optional[ValidationJsonGenerator] = None, + intime_model_selector: Optional[IntimeModelSelector] = None, + convert_to_fed_event: Optional[ConvertToFedEvent] = None, + analytics_receiver: Optional[AnalyticsReceiver] = None, + model_persistor: Optional[ModelPersistor] = None, + model_locator: Optional[ModelLocator] = None, + ): + """BaseFedJob. + + By default configures ValidationJsonGenerator, IntimeModelSelector, ConvertToFedEvent. + + If provided, configures AnalyticsReceiver, ModelPersistor, ModelLocator. + + User must add controllers and executors. + + Args: + name (name, optional): name of the job. Defaults to "fed_job". + min_clients (int, optional): the minimum number of clients for the job. Defaults to 1. + mandatory_clients (List[str], optional): mandatory clients to run the job. Default None. + key_metric (str, optional): Metric used to determine if the model is globally best. + if metrics are a `dict`, `key_metric` can select the metric used for global model selection. + Defaults to "accuracy". + validation_json_generator (ValidationJsonGenerator, optional): A component for generating validation results. + if not provided, a ValidationJsonGenerator will be configured. + intime_model_selector: (IntimeModelSelector, optional): A component for select the model. + if not provided, an IntimeModelSelector will be configured. + convert_to_fed_event: (ConvertToFedEvent, optional): A component to covert certain events to fed events. + if not provided, a ConvertToFedEvent object will be created. + analytics_receiver (AnlyticsReceiver, optional): Receive analytics. + model_persistor (optional, ModelPersistor): how to persist the model. + model_locator (optional, ModelLocator): how to locate the model. + """ + super().__init__( + name=name, + min_clients=min_clients, + mandatory_clients=mandatory_clients, + ) + + if validation_json_generator: + validate_object_for_job("validation_json_generator", validation_json_generator, ValidationJsonGenerator) + else: + validation_json_generator = ValidationJsonGenerator() + self.to_server(id="json_generator", obj=validation_json_generator) + + if intime_model_selector: + validate_object_for_job("intime_model_selector", intime_model_selector, IntimeModelSelector) + self.to_server(id="model_selector", obj=intime_model_selector) + elif key_metric: + self.to_server(id="model_selector", obj=IntimeModelSelector(key_metric=key_metric)) + + if convert_to_fed_event: + validate_object_for_job("convert_to_fed_event", convert_to_fed_event, ConvertToFedEvent) + else: + convert_to_fed_event = ConvertToFedEvent(events_to_convert=[ANALYTIC_EVENT_TYPE]) + self.convert_to_fed_event = convert_to_fed_event + + if analytics_receiver: + validate_object_for_job("analytics_receiver", analytics_receiver, AnalyticsReceiver) + self.to_server(id="receiver", obj=analytics_receiver) + + if model_persistor: + validate_object_for_job("persistor", model_persistor, ModelPersistor) + self.to_server(id="persistor", obj=model_persistor) + + if model_locator: + validate_object_for_job("locator", model_locator, ModelLocator) + self.to_server(id="locator", obj=model_locator) + + def set_up_client(self, target: str): + self.to(id="event_to_fed", obj=self.convert_to_fed_event, target=target) diff --git a/web/src/components/code.astro b/web/src/components/code.astro index c7e8e69c23..efec65e376 100644 --- a/web/src/components/code.astro +++ b/web/src/components/code.astro @@ -206,7 +206,7 @@ const jobCode_pt = ` from cifar10_pt_fl import Net from nvflare.app_common.workflows.fedavg import FedAvg -from nvflare.app_opt.pt.job_config.base_fed_job import BaseFedJob +from nvflare.app_opt.pt.job_config.base_fed_job import PTBaseFedJob from nvflare.job_config.script_runner import ScriptRunner if __name__ == "__main__": @@ -214,8 +214,8 @@ if __name__ == "__main__": num_rounds = 2 train_script = "cifar10_pt_fl.py" - # Create BaseFedJob with initial model - job = BaseFedJob( + # Create PTBaseFedJob with initial model + job = PTBaseFedJob( name="cifar10_pt_fedavg", initial_model=Net(), ) @@ -425,7 +425,7 @@ const jobCode_lt = ` from cifar10_lightning_fl import LitNet from nvflare.app_common.workflows.fedavg import FedAvg -from nvflare.app_opt.pt.job_config.base_fed_job import BaseFedJob +from nvflare.app_opt.pt.job_config.base_fed_job import PTBaseFedJob from nvflare.job_config.script_runner import ScriptRunner if __name__ == "__main__": @@ -433,8 +433,8 @@ if __name__ == "__main__": num_rounds = 2 train_script = "cifar10_lightning_fl.py" - # Create BaseFedJob with initial model - job = BaseFedJob( + # Create PTBaseFedJob with initial model + job = PTBaseFedJob( name="cifar10_lightning_fedavg", initial_model=LitNet(), ) @@ -587,7 +587,7 @@ const jobCode_tf = ` from cifar10_tf_fl import TFNet from nvflare.app_common.workflows.fedavg import FedAvg -from nvflare.app_opt.tf.job_config.base_fed_job import BaseFedJob +from nvflare.app_opt.tf.job_config.base_fed_job import TFBaseFedJob from nvflare.job_config.script_runner import FrameworkType, ScriptRunner if __name__ == "__main__": @@ -595,8 +595,8 @@ if __name__ == "__main__": num_rounds = 2 train_script = "cifar10_tf_fl.py" - # Create BaseFedJob with initial model - job = BaseFedJob( + # Create TFBaseFedJob with initial model + job = TFBaseFedJob( name="cifar10_tf_fedavg", initial_model=TFNet(input_shape=(None, 32, 32, 3)), ) @@ -665,7 +665,7 @@ const frameworks = [ framework: "pytorch", title: "Job Code (fedavg_cifar10_pt_job.py)", description: - "Lastly we construct the job with our 'cifar10_pt_fl.py' client script and 'FedAvg' server controller. The BaseFedJob automatically configures components for model persistence, model selection, and TensorBoard streaming. We then run the job with the FL simulator.", + "Lastly we construct the job with our 'cifar10_pt_fl.py' client script and 'FedAvg' server controller. The PTBaseFedJob automatically configures components for model persistence, model selection, and TensorBoard streaming. We then run the job with the FL simulator.", code: jobCode_pt, }, { @@ -719,7 +719,7 @@ const frameworks = [ framework: "lightning", title: "Job Code (fedavg_cifar10_lightning_job.py)", description: - "Lastly we construct the job with our 'cifar10_lightning_fl.py' client script and 'FedAvg' server controller. The BaseFedJob automatically configures components for model persistence, model selection, and TensorBoard streaming. We then run the job with the FL simulator.", + "Lastly we construct the job with our 'cifar10_lightning_fl.py' client script and 'FedAvg' server controller. The PTBaseFedJob automatically configures components for model persistence, model selection, and TensorBoard streaming. We then run the job with the FL simulator.", code: jobCode_lt, }, { @@ -773,7 +773,7 @@ const frameworks = [ framework: "tensorflow", title: "Job Code (fedavg_cifar10_tf_job.py)", description: - "Lastly we construct the job with our 'cifar10_tf_fl.py' client script and 'FedAvg' server controller. The BaseFedJob automatically configures components for model persistence, model selection, and TensorBoard streaming. We then run the job with the FL simulator.", + "Lastly we construct the job with our 'cifar10_tf_fl.py' client script and 'FedAvg' server controller. The TFBaseFedJob automatically configures components for model persistence, model selection, and TensorBoard streaming. We then run the job with the FL simulator.", code: jobCode_tf, }, { From 2a8826f0f98de45d2aa4680780acfb8a341a47d8 Mon Sep 17 00:00:00 2001 From: Sean Yang Date: Mon, 16 Dec 2024 10:40:09 -0800 Subject: [PATCH 2/2] class renaming --- docs/programming_guide/fed_job_api.rst | 2 +- .../nvflare_lightning_getting_started.ipynb | 8 +++---- .../pt/nvflare_pt_getting_started.ipynb | 8 +++---- .../tf/nvflare_tf_getting_started.ipynb | 8 +++---- nvflare/app_opt/pt/job_config/fed_avg.py | 4 ++-- .../app_opt/pt/job_config/fed_sag_mlflow.py | 4 ++-- .../job_config/{base_fed_job.py => pt_job.py} | 6 ++--- nvflare/app_opt/tf/job_config/fed_avg.py | 4 ++-- .../job_config/{base_fed_job.py => tf_job.py} | 6 ++--- .../{base_fed_job.py => common_job.py} | 4 ++-- web/src/components/code.astro | 24 +++++++++---------- 11 files changed, 39 insertions(+), 39 deletions(-) rename nvflare/app_opt/pt/job_config/{base_fed_job.py => pt_job.py} (97%) rename nvflare/app_opt/tf/job_config/{base_fed_job.py => tf_job.py} (97%) rename nvflare/job_config/{base_fed_job.py => common_job.py} (99%) diff --git a/docs/programming_guide/fed_job_api.rst b/docs/programming_guide/fed_job_api.rst index 0474b9dbc2..b84b131969 100644 --- a/docs/programming_guide/fed_job_api.rst +++ b/docs/programming_guide/fed_job_api.rst @@ -366,7 +366,7 @@ The FedAvgJob automatically adds the FedAvg controller, PTFileModelPersistor and For more examples of job patterns, see: -* :class:`BaseFedJob` +* :class:`CommonJob` * :class:`FedAvgJob` (pytorch) * :class:`FedAvgJob` (tensorflow) * :class:`CCWFJob` diff --git a/examples/getting_started/pt/nvflare_lightning_getting_started.ipynb b/examples/getting_started/pt/nvflare_lightning_getting_started.ipynb index fa91c994b7..c2858e7946 100644 --- a/examples/getting_started/pt/nvflare_lightning_getting_started.ipynb +++ b/examples/getting_started/pt/nvflare_lightning_getting_started.ipynb @@ -321,8 +321,8 @@ "#### 2. Define a FedJob\n", "The `FedJob` is used to define how controllers and executors are placed within a federated job using the `to(object, target)` routine.\n", "\n", - "Here we use a PyTorch `PTBaseFedJob`, where we can define the job name and the initial global model.\n", - "The `PTBaseFedJob` automatically configures components for model persistence, model selection, and TensorBoard streaming for convenience." + "Here we use a PyTorch `PTJob`, where we can define the job name and the initial global model.\n", + "The `PTJob` automatically configures components for model persistence, model selection, and TensorBoard streaming for convenience." ] }, { @@ -335,10 +335,10 @@ "from src.lit_net import LitNet\n", "\n", "from nvflare.app_common.workflows.fedavg import FedAvg\n", - "from nvflare.app_opt.pt.job_config.base_fed_job import PTBaseFedJob\n", + "from nvflare.app_opt.pt.job_config.pt_job import PTJob\n", "from nvflare.job_config.script_runner import ScriptRunner\n", "\n", - "job = PTBaseFedJob(\n", + "job = PTJob(\n", " name=\"cifar10_lightning_fedavg\",\n", " initial_model=LitNet(),\n", ")" diff --git a/examples/getting_started/pt/nvflare_pt_getting_started.ipynb b/examples/getting_started/pt/nvflare_pt_getting_started.ipynb index e6c474b4fd..fb7f25a6cc 100644 --- a/examples/getting_started/pt/nvflare_pt_getting_started.ipynb +++ b/examples/getting_started/pt/nvflare_pt_getting_started.ipynb @@ -263,8 +263,8 @@ "#### 2. Define a FedJob\n", "The `FedJob` is used to define how controllers and executors are placed within a federated job using the `to(object, target)` routine.\n", "\n", - "Here we use a PyTorch `PTBaseFedJob`, where we can define the job name and the initial global model.\n", - "The `PTBaseFedJob` automatically configures components for model persistence, model selection, and TensorBoard streaming for convenience." + "Here we use a PyTorch `PTJob`, where we can define the job name and the initial global model.\n", + "The `PTJob` automatically configures components for model persistence, model selection, and TensorBoard streaming for convenience." ] }, { @@ -277,10 +277,10 @@ "from src.net import Net\n", "\n", "from nvflare.app_common.workflows.fedavg import FedAvg\n", - "from nvflare.app_opt.pt.job_config.base_fed_job import PTBaseFedJob\n", + "from nvflare.app_opt.pt.job_config.pt_job import PTJob\n", "from nvflare.job_config.script_runner import ScriptRunner\n", "\n", - "job = PTBaseFedJob(\n", + "job = PTJob(\n", " name=\"cifar10_pt_fedavg\",\n", " initial_model=Net(),\n", ")" diff --git a/examples/getting_started/tf/nvflare_tf_getting_started.ipynb b/examples/getting_started/tf/nvflare_tf_getting_started.ipynb index 9abafe0de2..a7870aa1db 100644 --- a/examples/getting_started/tf/nvflare_tf_getting_started.ipynb +++ b/examples/getting_started/tf/nvflare_tf_getting_started.ipynb @@ -253,8 +253,8 @@ "#### 2. Define a FedJob\n", "The `FedJob` is used to define how controllers and executors are placed within a federated job using the `to(object, target)` routine.\n", "\n", - "Here we use a TensorFlow `TFBaseFedJob`, where we can define the job name and the initial global model.\n", - "The `TFBaseFedJob` automatically configures components for model persistence, model selection, and TensorBoard streaming for convenience." + "Here we use a TensorFlow `TFJob`, where we can define the job name and the initial global model.\n", + "The `TFJob` automatically configures components for model persistence, model selection, and TensorBoard streaming for convenience." ] }, { @@ -267,10 +267,10 @@ "from src.tf_net import TFNet\n", "\n", "from nvflare.app_common.workflows.fedavg import FedAvg\n", - "from nvflare.app_opt.tf.job_config.base_fed_job import TFBaseFedJob\n", + "from nvflare.app_opt.tf.job_config.tf_job import TFJob\n", "from nvflare.job_config.script_runner import FrameworkType, ScriptRunner\n", "\n", - "job = TFBaseFedJob(\n", + "job = TFJob(\n", " name=\"cifar10_tf_fedavg\",\n", " initial_model=TFNet(),\n", ")" diff --git a/nvflare/app_opt/pt/job_config/fed_avg.py b/nvflare/app_opt/pt/job_config/fed_avg.py index f0544aa45c..300f401ba4 100644 --- a/nvflare/app_opt/pt/job_config/fed_avg.py +++ b/nvflare/app_opt/pt/job_config/fed_avg.py @@ -16,10 +16,10 @@ import torch.nn as nn from nvflare.app_common.workflows.fedavg import FedAvg -from nvflare.app_opt.pt.job_config.base_fed_job import PTBaseFedJob +from nvflare.app_opt.pt.job_config.pt_job import PTJob -class FedAvgJob(PTBaseFedJob): +class FedAvgJob(PTJob): def __init__( self, initial_model: nn.Module, diff --git a/nvflare/app_opt/pt/job_config/fed_sag_mlflow.py b/nvflare/app_opt/pt/job_config/fed_sag_mlflow.py index d6f707d4db..42ac67535d 100644 --- a/nvflare/app_opt/pt/job_config/fed_sag_mlflow.py +++ b/nvflare/app_opt/pt/job_config/fed_sag_mlflow.py @@ -19,12 +19,12 @@ from nvflare.app_common.aggregators import InTimeAccumulateWeightedAggregator from nvflare.app_common.shareablegenerators import FullModelShareableGenerator from nvflare.app_common.workflows.scatter_and_gather import ScatterAndGather -from nvflare.app_opt.pt.job_config.base_fed_job import PTBaseFedJob +from nvflare.app_opt.pt.job_config.pt_job import PTJob from nvflare.app_opt.tracking.mlflow.mlflow_receiver import MLflowReceiver from nvflare.app_opt.tracking.mlflow.mlflow_writer import MLflowWriter -class SAGMLFlowJob(PTBaseFedJob): +class SAGMLFlowJob(PTJob): def __init__( self, initial_model: nn.Module, diff --git a/nvflare/app_opt/pt/job_config/base_fed_job.py b/nvflare/app_opt/pt/job_config/pt_job.py similarity index 97% rename from nvflare/app_opt/pt/job_config/base_fed_job.py rename to nvflare/app_opt/pt/job_config/pt_job.py index dbc2d0a293..b3f050a500 100644 --- a/nvflare/app_opt/pt/job_config/base_fed_job.py +++ b/nvflare/app_opt/pt/job_config/pt_job.py @@ -25,10 +25,10 @@ from nvflare.app_opt.pt.job_config.model import PTModel from nvflare.app_opt.tracking.tb.tb_receiver import TBAnalyticsReceiver from nvflare.job_config.api import validate_object_for_job -from nvflare.job_config.base_fed_job import BaseFedJob +from nvflare.job_config.common_job import CommonJob -class PTBaseFedJob(BaseFedJob): +class PTJob(CommonJob): def __init__( self, initial_model: nn.Module = None, @@ -43,7 +43,7 @@ def __init__( model_persistor: Optional[ModelPersistor] = None, model_locator: Optional[ModelLocator] = None, ): - """PyTorch BaseFedJob. + """PyTorch CommonJob. Configures ValidationJsonGenerator, IntimeModelSelector, AnalyticsReceiver, ConvertToFedEvent. diff --git a/nvflare/app_opt/tf/job_config/fed_avg.py b/nvflare/app_opt/tf/job_config/fed_avg.py index 7449e0f583..070aac6159 100644 --- a/nvflare/app_opt/tf/job_config/fed_avg.py +++ b/nvflare/app_opt/tf/job_config/fed_avg.py @@ -16,10 +16,10 @@ import tensorflow as tf from nvflare.app_common.workflows.fedavg import FedAvg -from nvflare.app_opt.tf.job_config.base_fed_job import TFBaseFedJob +from nvflare.app_opt.tf.job_config.tf_job import TFJob -class FedAvgJob(TFBaseFedJob): +class FedAvgJob(TFJob): def __init__( self, initial_model: tf.keras.Model, diff --git a/nvflare/app_opt/tf/job_config/base_fed_job.py b/nvflare/app_opt/tf/job_config/tf_job.py similarity index 97% rename from nvflare/app_opt/tf/job_config/base_fed_job.py rename to nvflare/app_opt/tf/job_config/tf_job.py index 51cab16914..259a3ea319 100644 --- a/nvflare/app_opt/tf/job_config/base_fed_job.py +++ b/nvflare/app_opt/tf/job_config/tf_job.py @@ -24,10 +24,10 @@ from nvflare.app_opt.tf.job_config.model import TFModel from nvflare.app_opt.tracking.tb.tb_receiver import TBAnalyticsReceiver from nvflare.job_config.api import validate_object_for_job -from nvflare.job_config.base_fed_job import BaseFedJob +from nvflare.job_config.common_job import CommonJob -class TFBaseFedJob(BaseFedJob): +class TFJob(CommonJob): def __init__( self, initial_model: tf.keras.Model = None, @@ -41,7 +41,7 @@ def __init__( analytics_receiver: Optional[AnalyticsReceiver] = None, model_persistor: Optional[ModelPersistor] = None, ): - """TensorFlow BaseFedJob. + """TensorFlow CommonJob. Configures ValidationJsonGenerator, IntimeModelSelector, TBAnalyticsReceiver, ConvertToFedEvent. diff --git a/nvflare/job_config/base_fed_job.py b/nvflare/job_config/common_job.py similarity index 99% rename from nvflare/job_config/base_fed_job.py rename to nvflare/job_config/common_job.py index c1dd26f543..c0d6d0b836 100644 --- a/nvflare/job_config/base_fed_job.py +++ b/nvflare/job_config/common_job.py @@ -24,7 +24,7 @@ from nvflare.job_config.api import FedJob, validate_object_for_job -class BaseFedJob(FedJob): +class CommonJob(FedJob): def __init__( self, name: str = "fed_job", @@ -38,7 +38,7 @@ def __init__( model_persistor: Optional[ModelPersistor] = None, model_locator: Optional[ModelLocator] = None, ): - """BaseFedJob. + """CommonJob. By default configures ValidationJsonGenerator, IntimeModelSelector, ConvertToFedEvent. diff --git a/web/src/components/code.astro b/web/src/components/code.astro index efec65e376..c8c8d95ce5 100644 --- a/web/src/components/code.astro +++ b/web/src/components/code.astro @@ -206,7 +206,7 @@ const jobCode_pt = ` from cifar10_pt_fl import Net from nvflare.app_common.workflows.fedavg import FedAvg -from nvflare.app_opt.pt.job_config.base_fed_job import PTBaseFedJob +from nvflare.app_opt.pt.job_config.pt_job import PTJob from nvflare.job_config.script_runner import ScriptRunner if __name__ == "__main__": @@ -214,8 +214,8 @@ if __name__ == "__main__": num_rounds = 2 train_script = "cifar10_pt_fl.py" - # Create PTBaseFedJob with initial model - job = PTBaseFedJob( + # Create PTJob with initial model + job = PTJob( name="cifar10_pt_fedavg", initial_model=Net(), ) @@ -425,7 +425,7 @@ const jobCode_lt = ` from cifar10_lightning_fl import LitNet from nvflare.app_common.workflows.fedavg import FedAvg -from nvflare.app_opt.pt.job_config.base_fed_job import PTBaseFedJob +from nvflare.app_opt.pt.job_config.pt_job import PTJob from nvflare.job_config.script_runner import ScriptRunner if __name__ == "__main__": @@ -433,8 +433,8 @@ if __name__ == "__main__": num_rounds = 2 train_script = "cifar10_lightning_fl.py" - # Create PTBaseFedJob with initial model - job = PTBaseFedJob( + # Create PTJob with initial model + job = PTJob( name="cifar10_lightning_fedavg", initial_model=LitNet(), ) @@ -587,7 +587,7 @@ const jobCode_tf = ` from cifar10_tf_fl import TFNet from nvflare.app_common.workflows.fedavg import FedAvg -from nvflare.app_opt.tf.job_config.base_fed_job import TFBaseFedJob +from nvflare.app_opt.tf.job_config.tf_job import TFJob from nvflare.job_config.script_runner import FrameworkType, ScriptRunner if __name__ == "__main__": @@ -595,8 +595,8 @@ if __name__ == "__main__": num_rounds = 2 train_script = "cifar10_tf_fl.py" - # Create TFBaseFedJob with initial model - job = TFBaseFedJob( + # Create TFJob with initial model + job = TFJob( name="cifar10_tf_fedavg", initial_model=TFNet(input_shape=(None, 32, 32, 3)), ) @@ -665,7 +665,7 @@ const frameworks = [ framework: "pytorch", title: "Job Code (fedavg_cifar10_pt_job.py)", description: - "Lastly we construct the job with our 'cifar10_pt_fl.py' client script and 'FedAvg' server controller. The PTBaseFedJob automatically configures components for model persistence, model selection, and TensorBoard streaming. We then run the job with the FL simulator.", + "Lastly we construct the job with our 'cifar10_pt_fl.py' client script and 'FedAvg' server controller. The PTJob automatically configures components for model persistence, model selection, and TensorBoard streaming. We then run the job with the FL simulator.", code: jobCode_pt, }, { @@ -719,7 +719,7 @@ const frameworks = [ framework: "lightning", title: "Job Code (fedavg_cifar10_lightning_job.py)", description: - "Lastly we construct the job with our 'cifar10_lightning_fl.py' client script and 'FedAvg' server controller. The PTBaseFedJob automatically configures components for model persistence, model selection, and TensorBoard streaming. We then run the job with the FL simulator.", + "Lastly we construct the job with our 'cifar10_lightning_fl.py' client script and 'FedAvg' server controller. The PTJob automatically configures components for model persistence, model selection, and TensorBoard streaming. We then run the job with the FL simulator.", code: jobCode_lt, }, { @@ -773,7 +773,7 @@ const frameworks = [ framework: "tensorflow", title: "Job Code (fedavg_cifar10_tf_job.py)", description: - "Lastly we construct the job with our 'cifar10_tf_fl.py' client script and 'FedAvg' server controller. The TFBaseFedJob automatically configures components for model persistence, model selection, and TensorBoard streaming. We then run the job with the FL simulator.", + "Lastly we construct the job with our 'cifar10_tf_fl.py' client script and 'FedAvg' server controller. The TFJob automatically configures components for model persistence, model selection, and TensorBoard streaming. We then run the job with the FL simulator.", code: jobCode_tf, }, {