Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for initializing private attributes without callable #974

Merged
merged 24 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
01b8a5c
Updated private_attrs initialization & Added testcases to test the same
ishant162 May 16, 2024
daeaa84
Fixed typo
ishant162 May 16, 2024
175883f
Updated Workflow_Interface_101_MNIST.ipynb & workflowinterface.rst
ishant162 May 17, 2024
ec1a6ef
Incorporated Internal review comments
ishant162 May 17, 2024
4d86169
Merge branch 'securefederatedai:develop' into update_private_attr_init
ishant162 May 20, 2024
151efa6
Incorporated Internal review comments
ishant162 May 20, 2024
e11bb20
Merge branch 'securefederatedai:develop' into update_private_attr_init
ishant162 May 22, 2024
874340e
Experimental Aggregator based workflow: Updated private_attrs initial…
ishant162 May 23, 2024
5049ba2
Fixed lint errors
ishant162 May 23, 2024
61b68eb
Bug fix: fx workspace create
ishant162 May 29, 2024
9b966e7
Workspace Export: Supports initialization of private attributes directly
ishant162 May 29, 2024
c968c3d
Fixed lint errors
ishant162 May 29, 2024
3632eb6
Incorporated Internal review comments
ishant162 May 30, 2024
a920ecf
Updated 101_torch_cnn_mnist private_attrs
ishant162 May 31, 2024
aa2692b
Updated workflow_interface tutorials 1001, 104_keras, 401_MNIST
ishant162 May 31, 2024
57eedd1
Incorporated Internal review comments
ishant162 Jun 5, 2024
c0a20f8
Resolving merge conflicts
ishant162 Jun 10, 2024
4a7b786
Merge branch 'develop' into update_private_attr_init
ishant162 Jun 10, 2024
3af0b73
Updated import
ishant162 Jun 10, 2024
d27a041
Fixed typo & updated federated plan
ishant162 Jun 11, 2024
2f516fc
Updated aggregator import
ishant162 Jun 12, 2024
aa6f790
Update docs/about/features_index/workflowinterface.rst
ParthMandaliya Jun 13, 2024
0930a5a
Update docs/about/features_index/workflowinterface.rst
ParthMandaliya Jun 13, 2024
a6342c0
Update docs/about/features_index/workflowinterface.rst
ParthMandaliya Jun 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 41 additions & 12 deletions docs/about/features_index/workflowinterface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,39 @@ The workflow interface formulates the experiment as a series of tasks, or a flow
Runtimes
========

A :code:`Runtime` defines where the flow will be executed, who the participants are in the experiment, and the private information that each participant has access to. In this experimental release, single node execution is supported using the :code:`LocalRuntime`. Let's see how a :code:`LocalRuntime` is created:
A :code:`Runtime` defines where the flow will be executed, who the participants are in the experiment, and the private information that each participant has access to. In this experimental release, single node execution is supported using the :code:`LocalRuntime`. Let's see how a :code:`LocalRuntime` is created.

.. code-block:: python

# Setup participants
aggregator = Aggregator()
aggregator.private_attributes = {}

# Setup collaborators with private attributes
collaborator_names = ['Portland', 'Seattle', 'Chandler','Bangalore']
collaborators = [Collaborator(name=name) for name in collaborator_names]
for idx, collaborator in enumerate(collaborators):
local_train = deepcopy(mnist_train)
local_test = deepcopy(mnist_test)
local_train.data = mnist_train.data[idx::len(collaborators)]
local_train.targets = mnist_train.targets[idx::len(collaborators)]
local_test.data = mnist_test.data[idx::len(collaborators)]
local_test.targets = mnist_test.targets[idx::len(collaborators)]
collaborator.private_attributes = {
'train_loader': torch.utils.data.DataLoader(local_train,batch_size=batch_size_train, shuffle=True),
'test_loader': torch.utils.data.DataLoader(local_test,batch_size=batch_size_train, shuffle=True)
}

local_runtime = LocalRuntime(aggregator=aggregator, collaborators=collaborators, backend='single_process')

Let's break this down, starting with the :code:`Aggregator` and :code:`Collaborator` components. These components represent the *Participants* in a Federated Learning experiment. Each participant has its own set of *private attributes* that represent the information / data specific to its role or requirements. As the name suggests these *private attributes* are accessible only to the particular participant, and are appropriately inserted into or filtered out of current Flow state when transferring from between Participants. For e.g. Collaborator private attributes are inserted into :code:`flow` when transitioning from Aggregator to Collaborator and are filtered out when transitioning from Collaborator to Aggregator.
ParthMandaliya marked this conversation as resolved.
Show resolved Hide resolved

In the above :code:`FederatedFlow`, each collaborator accesses train and test datasets via *private attributes* :code:`train_loader` and :code:`test_loader`. These *private attributes* need to be set in form of a dictionary(user defined), where the key is the name of the attribute and the value is the object. In this example :code:`collaborator.private_attributes` sets the collaborator *private attributes* :code:`train_loader` and :code:`test_loader` that are accessed by collaborator steps (:code:`aggregated_model_validation`, :code:`train` and :code:`local_model_validation`).
ParthMandaliya marked this conversation as resolved.
Show resolved Hide resolved

There is another way of initializing private attributes in which *private attributes* need to be set using a (user defined) callback function while instantiating the participant.
ParthMandaliya marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: python

# Aggregator
aggregator_ = Aggregator()

Expand Down Expand Up @@ -181,25 +210,25 @@ A :code:`Runtime` defines where the flow will be executed, who the participants

local_runtime = LocalRuntime(aggregator=aggregator_, collaborators=collaborators)

Let's break this down, starting with the :code:`Aggregator` and :code:`Collaborator` components. These components represent the *Participants* in a Federated Learning experiment. Each participant has its own set of *private attributes* that represent the information / data specific to its role or requirements. As the name suggests these *private attributes* are accessible only to the particular participant, and are appropriately inserted into or filtered out of current Flow state when transferring from between Participants. For e.g. Collaborator private attributes are inserted into :code:`flow` when transitioning from Aggregator to Collaborator and are filtered out when transitioning from Collaborator to Aggregator.

In the above :code:`FederatedFlow`, each collaborator accesses train and test datasets via *private attributes* :code:`train_loader` and :code:`test_loader`. These *private attributes* need to be set using a (user defined) callback function while instantiating the participant. Participant *private attributes* are returned by the callback function in form of a dictionary, where the key is the name of the attribute and the value is the object.
Participant *private attributes* are returned by the callback function in form of a dictionary, where the key is the name of the attribute and the value is the object. In this example callback function :code:`callable_to_initialize_collaborator_private_attributes()` returns :code:`train_loader` and :code:`test_loader` in the form of a dictionary.

**Note:**If both callable and private attributes are provided, the initialization will prioritize the private attributes through the :code:`callable` function.

In this example callback function :code:`callable_to_initialize_collaborator_private_attributes()` returns the collaborator private attributes :code:`train_loader` and :code:`test_loader` that are accessed by collaborator steps (:code:`aggregated_model_validation`, :code:`train` and :code:`local_model_validation`). Some important points to remember while creating callback function and private attributes are:
Some important points to remember while creating callback function and private attributes are:

- Callback Function needs to be defined by the user and should return the *private attributes* required by the participant in form of a key/value pair
- In above example multiple collaborators have the same callback function. Depending on the Federated Learning requirements, user can specify unique callback functions for each Participant
- If no Callback Function is specified then the Participant shall not have any *private attributes*
- Callback function can be provided with any parameters required as arguments. In this example, parameters essential for the callback function are supplied with corresponding values bearing *same names* during the instantiation of the Collaborator
- Callback Function needs to be defined by the user and should return the *private attributes* required by the participant in form of a key/value pair
- Callback function can be provided with any parameters required as arguments. In this example, parameters essential for the callback function are supplied with corresponding values bearing *same names* during the instantiation of the Collaborator

* :code:`index`: Index of the particular collaborator needed to shard the dataset
* :code:`n_collaborators`: Total number of collaborators in which the dataset is sharded
* :code:`batch_size`: For the train and test loaders
* :code:`train_dataset`: Train Dataset to be sharded between n_collaborators
* :code:`test_dataset`: Test Dataset to be sharded between n_collaborators

- Callback function needs to be specified by user while instantiating the participant. Callback function is invoked by the OpenFL runtime at the time participant is created and once created these attributes cannot be modified
- Private attributes are accessible only in the Participant steps
- Callback function needs to be specified by user while instantiating the participant. Callback function is invoked by the OpenFL runtime at the time participant is created and once created these attributes cannot be modified
- If no Callback Function or private attributes is specified then the Participant shall not have any *private attributes*
- In above example multiple collaborators have the same callback function or private attributes. Depending on the Federated Learning requirements, user can specify unique callback function or private attributes for each Participant
- *Private attributes* needs to be set after instantiating the participant.

Now let's see how the runtime for a flow is assigned, and the flow gets run:

Expand Down Expand Up @@ -378,4 +407,4 @@ Our goal is to make it a one line change to configure where and how a flow is ex
# A future example of how the same flow could be run on distributed infrastructure
federated_runtime = FederatedRuntime(...)
flow.runtime = federated_runtime
flow.run()
flow.run()
Loading
Loading