Add CollaboratorSerialiser middleware for serialisation/deserialisation between collaborator and aggregator client#1476
Conversation
|
The changes in tests mostly include moving tests between the now appropriate modules and/or renaming them. |
CollaboratorSerialiser middleware for serialisation/deserialisation between collaborator and aggregator clientCollaboratorSerialiser middleware for serialisation/deserialisation between collaborator and aggregator client
| def serialise(self, tensor_key, nparray, lossless=True): | ||
| """Construct the NamedTensor Protobuf. | ||
|
|
||
| def find_dependencies(self, tensor_key, send_model_deltas): |
There was a problem hiding this comment.
This method has been moved to Collaborator after removing these lines
if self.compression_pipeline.is_lossy():
new_tags = ("aggregated", "delta", "lossy_compressed")
else:
new_tags = ("aggregated", "delta", "compressed")
tensor_key_dependencies.append(
TensorKey(tensor_name, origin, round_number, report, new_tags)
)
As can be seen from the usage of the returned dependencies in the Collaborator.get_data_for_tensorkey, only the first tensor dependency is used, which is always
TensorKey(tensor_name, origin, round_number - 1, report, tags)
There was a problem hiding this comment.
I don't think that's quite right. When use_delta_updates is set to true, there are two dependencies: the prior version of the model, and the delta that should be applied (either compressed with a lossless or lossy pipeline) to that model to bring it to the current version. The 2nd tensor dependency (tensor_dependency[1]) is used later in the function that you reference here. If you're only seeing the first tensor dependency for every run, then what's likely happening is that db_store_rounds for the collaborator is set to 1 (it needs to be set to 2 in order to retain the prior version of the model locally). Before these lines are removed, you should add tests for use_delta_updates=True and use a lossy compression pipeline (such as this one).
| write_logs=False, | ||
| callbacks: Optional[List] = [], | ||
| secure_aggregation=False, | ||
| serialisation_middleware: CollaboratorSerialiser = None, |
There was a problem hiding this comment.
We can also consider removing client completely from the collaborator since the middleware already has the client object.
The client object is currently used by the secure aggregation callback which could potentially also work with the middleware given the changes proposed in #1518
There was a problem hiding this comment.
On the contrary, I'm wondering whether the collaborator shouldn't just have a client object, while any "middlewares" are added as decorators to the AggregatorGRPCClient class. Those decorators could receive certain configurations via the FL plan (such as the compression algo).
WDYT?
There was a problem hiding this comment.
Ah, I see your point, I hadn't considered using decorators here!
I went with "middleware" approach as I feel it is easier to "chain" - multiple layers can be used and each of them can be easily added/removed without affecting any of the other layers.
With the middleware approach, the only change required to switch between gRPC and REST would be in how the client is initialized. Similarly, in the future if we decide to make changes to the compression pipeline or such, we can look to make changes only the serialisation layer.
Gotta admit, I’m a bit biased toward this approach 😁 but totally open to other perspectives!
There was a problem hiding this comment.
I am leaning towards having entire approach encapsulated within the client (@teoparvanov's approach is one of the ways to do that).
The current implementation removes compression pipeline from the collaborator and it adds a new serializer object. From an abstraction standpoint it would be worth asking: does a collaborator need to know about serialization? Having it all in the client marks that separation very well.
I see the benefit in your approach of having a middleware when a different use case leverages it. Could you list any planned features that may benefit from this approach?
There was a problem hiding this comment.
My original point was that, once we have sorted out the secure aggregation serialisation, we can fully replace the client object with this proposed class object.
A key argument for keeping this logic separate from the client is the potential addition of a REST client. With the approach proposed in this PR, the serialiser would simply reference the enabled transport client, REST or gRPC.
An argument can be made for going with the decorator approach as mentioned by Teo but in my opinion, the middleware approach provides us more flexibility.
| # def test_find_dependencies(collaborator_mock, tensor_key): | ||
| # """Test that find_dependencies works correctly.""" | ||
| # collaborator_mock.use_delta_updates = True | ||
| # tensor_name, origin, round_number, report, tags = tensor_key | ||
| # round_number = 2 | ||
| # tensor_key = TensorKey( | ||
| # tensor_name, origin, round_number, report, ('model',) | ||
| # ) | ||
| # tensor_key_dependencies = collaborator_mock._find_dependencies(tensor_key) | ||
|
|
||
| # assert len(tensor_key_dependencies) == 2 | ||
| # tensor_key_dependency_0, tensor_key_dependency_1 = tensor_key_dependencies | ||
| # assert tensor_key_dependency_0.round_number == round_number - 1 | ||
| # assert tensor_key_dependency_0.tags == tensor_key.tags | ||
| # assert tensor_key_dependency_1.tags == ('aggregated', 'delta', 'compressed') | ||
|
|
||
|
|
||
| # def test_find_dependencies_is_lossy(collaborator_mock, tensor_key): | ||
| # """Test that find_dependencies works correctly with lossy_compressed.""" | ||
| # collaborator_mock.use_delta_updates = True | ||
| # collaborator_mock.compression_pipeline.is_lossy = mock.Mock(return_value=True) | ||
| # tensor_name, origin, round_number, report, tags = tensor_key | ||
| # round_number = 2 | ||
| # tensor_key = TensorKey( | ||
| # tensor_name, origin, round_number, report, ('model',) | ||
| # ) | ||
| # tensor_key_dependencies = collaborator_mock._find_dependencies(tensor_key) | ||
|
|
||
| # assert len(tensor_key_dependencies) == 2 | ||
| # tensor_key_dependency_0, tensor_key_dependency_1 = tensor_key_dependencies | ||
| # assert tensor_key_dependency_0.round_number == round_number - 1 | ||
| # assert tensor_key_dependency_0.tags == tensor_key.tags | ||
| # assert tensor_key_dependency_1.tags == ('aggregated', 'delta', 'lossy_compressed') |
There was a problem hiding this comment.
These tests are commented out and planned to be removed, refer #1476 (comment)
There was a problem hiding this comment.
Hi @theakshaypant , thanks for starting this effort.
To begin with, could you add a "why" section in the PR description? In addition to the obvious encapsulation benefits, what framework capabilities do you expect this refactoring to enable down the road?
Additional comments based on the code itself:
| write_logs=False, | ||
| callbacks: Optional[List] = [], | ||
| secure_aggregation=False, | ||
| serialisation_middleware: CollaboratorSerialiser = None, |
There was a problem hiding this comment.
On the contrary, I'm wondering whether the collaborator shouldn't just have a client object, while any "middlewares" are added as decorators to the AggregatorGRPCClient class. Those decorators could receive certain configurations via the FL plan (such as the compression algo).
WDYT?
| from openfl.pipelines import TensorCodec | ||
|
|
||
|
|
||
| class CollaboratorSerialiser: |
There was a problem hiding this comment.
This class indeed looks like a decorator of AggregatorGRPCClient, as it implements the same interface, but adds some orthogonal aspects like encoding/decoding via the tensor codec.
@teoparvanov Thanks for the comments! Updated the PR description. |
psfoley
left a comment
There was a problem hiding this comment.
I haven't gotten to the point of reviewing the architectural changes proposed, but I see some changes that appear to break the delta update functionality. I see some positive steps taken overall - reducing code within the collaborator is always a good thing. 2nd half of the review to come tomorrow.
| def serialise(self, tensor_key, nparray, lossless=True): | ||
| """Construct the NamedTensor Protobuf. | ||
|
|
||
| def find_dependencies(self, tensor_key, send_model_deltas): |
There was a problem hiding this comment.
I don't think that's quite right. When use_delta_updates is set to true, there are two dependencies: the prior version of the model, and the delta that should be applied (either compressed with a lossless or lossy pipeline) to that model to bring it to the current version. The 2nd tensor dependency (tensor_dependency[1]) is used later in the function that you reference here. If you're only seeing the first tensor dependency for every run, then what's likely happening is that db_store_rounds for the collaborator is set to 1 (it needs to be set to 2 in order to retain the prior version of the model locally). Before these lines are removed, you should add tests for use_delta_updates=True and use a lossy compression pipeline (such as this one).
There was a problem hiding this comment.
While I understand the motivation behind adding a new component, this adds significant LOC for what is effectively adding deserialize/serialize calls into each RPC.
IMO let us migrate those calls to grpc client to land a minimum API change version.
When we realize the need for a serializer to do more than what is being done today, I clearly see value in having a dedicated component that forwards across RPC methods like we do here.
| write_logs=False, | ||
| callbacks: Optional[List] = [], | ||
| secure_aggregation=False, | ||
| serialisation_middleware: CollaboratorSerialiser = None, |
There was a problem hiding this comment.
I am leaning towards having entire approach encapsulated within the client (@teoparvanov's approach is one of the ways to do that).
The current implementation removes compression pipeline from the collaborator and it adds a new serializer object. From an abstraction standpoint it would be worth asking: does a collaborator need to know about serialization? Having it all in the client marks that separation very well.
I see the benefit in your approach of having a middleware when a different use case leverages it. Could you list any planned features that may benefit from this approach?
* Changes to reduce unnecessary allocations Signed-off-by: Shah, Karan <kbshah1998@outlook.com> * Remove compression/decompression for _prepare_trained Signed-off-by: Shah, Karan <kbshah1998@outlook.com> * Execute SendLocalTaskResults in a queued call Signed-off-by: Shah, Karan <kbshah1998@outlook.com> * Update test with the remove col_name argument Signed-off-by: Shah, Karan <kbshah1998@outlook.com> * Use allclose instead of equal Signed-off-by: Shah, Karan <kbshah1998@outlook.com> * Revert "Remove compression/decompression for _prepare_trained" This reverts commit cb0adeb. Signed-off-by: Shah, Karan <kbshah1998@outlook.com> * Move lock decorator to common Signed-off-by: Shah, Karan <kbshah1998@outlook.com> --------- Signed-off-by: Shah, Karan <kbshah1998@outlook.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…update utilities for delta operations Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
* setuptools upgrade pr Signed-off-by: payalcha <payal.chaurasiya@intel.com> * setuptools upgrade pr Signed-off-by: payalcha <payal.chaurasiya@intel.com> --------- Signed-off-by: payalcha <payal.chaurasiya@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…aml file (securefederatedai#1479) * Taking latest nbdev as previous giving error Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> * Taking latest nbdev as previous giving error Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> * Security TLS certificate report tests Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> * Security TLS certificate report tests Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> * FedEval fix Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> * Small change Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> * Logs correction Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> * Format changes Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> * To streamline Collaborator yaml for torch/mnist with all other cols.yaml file Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> * change tp fpdf2 from fpdf Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> * change tp fpdf2 from fpdf Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> * review comments Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> * Update taskrunner tutorial Signed-off-by: payalcha <payal.chaurasiya@intel.com> --------- Signed-off-by: Chaurasiya, Payal <payal.chaurasiya@intel.com> Signed-off-by: payalcha <payal.chaurasiya@intel.com> Co-authored-by: Noopur <noopur@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…curefederatedai#1470) * chore: update openfl version to 1.8 (securefederatedai#1464) Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com> * fix(secagg): correct module name to import module (securefederatedai#1467) Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com> * fix(secagg): correct module name to import module (securefederatedai#1466) Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com> Signed-off-by: kta-intel <kevin.ta@intel.com> * update README.md Signed-off-by: kta-intel <kevin.ta@intel.com> * 1.8: Raise error if data is not found when running flower-app-pytorch workspace (securefederatedai#1473) * fix(secagg): correct module name to import module (securefederatedai#1466) Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com> Signed-off-by: kta-intel <kevin.ta@intel.com> * raise error if data is not found Signed-off-by: kta-intel <kevin.ta@intel.com> --------- Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com> Signed-off-by: kta-intel <kevin.ta@intel.com> Co-authored-by: Akshay Pant <16561942+theakshaypant@users.noreply.github.com> * add fqdn flag to aggregator commands, fix auto_shutdown key, add additional notes to experiment configuration Signed-off-by: kta-intel <kevin.ta@intel.com> * restructure: remove trailing whitespace (securefederatedai#1483) Signed-off-by: Pant, Akshay <akshay.pant@intel.com> --------- Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com> Signed-off-by: kta-intel <kevin.ta@intel.com> Signed-off-by: Pant, Akshay <akshay.pant@intel.com> Co-authored-by: Akshay Pant <16561942+theakshaypant@users.noreply.github.com> Co-authored-by: Noopur <noopur@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…rkspace (securefederatedai#1472) * fix(secagg): correct module name to import module (securefederatedai#1466) Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com> Signed-off-by: kta-intel <kevin.ta@intel.com> * raise error if data is not found Signed-off-by: kta-intel <kevin.ta@intel.com> --------- Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com> Signed-off-by: kta-intel <kevin.ta@intel.com> Co-authored-by: Akshay Pant <16561942+theakshaypant@users.noreply.github.com> Co-authored-by: Noopur <noopur@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…tedai#1485) Signed-off-by: noopur <noopur@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
Signed-off-by: Teodor Parvanov <teodor.parvanov@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…1494) * Test Flower automation Signed-off-by: noopur <noopur@intel.com> * Run only once Signed-off-by: noopur <noopur@intel.com> * Added Flower as separate job Signed-off-by: noopur <noopur@intel.com> * Extra closing bracket Signed-off-by: noopur <noopur@intel.com> * Removed dependencies installation step Signed-off-by: noopur <noopur@intel.com> * Correction of step name and logging Signed-off-by: noopur <noopur@intel.com> * New marker for flower model Signed-off-by: noopur <noopur@intel.com> * Separate workflow for Flower Signed-off-by: noopur <noopur@intel.com> * Changes for dockerized ws Signed-off-by: noopur <noopur@intel.com> * Modified test name to reflect flower model Signed-off-by: noopur <noopur@intel.com> --------- Signed-off-by: noopur <noopur@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
securefederatedai#1488) (securefederatedai#1490) * bind socket to a specific interface * add input validation and allow list * address filepath coverity issue by creating a function to check path safety using set of allowed characters * pin upper bound to flwr * formatting --------- Signed-off-by: kta-intel <kevin.ta@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
Signed-off-by: noopur <noopur@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…ai#1495) * Add trufflehog to scan secrets in repo and logs file Signed-off-by: payalcha <payal.chaurasiya@intel.com> * title fix Signed-off-by: payalcha <payal.chaurasiya@intel.com> * Review comments Signed-off-by: payalcha <payal.chaurasiya@intel.com> --------- Signed-off-by: payalcha <payal.chaurasiya@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
* Change openfl version from 1.8 to 1.9.0-dev Signed-off-by: noopur <noopur@intel.com> * Change openfl version from 1.8 to 1.9.0.dev Signed-off-by: noopur <noopur@intel.com> * Modified version file as well Signed-off-by: noopur <noopur@intel.com> --------- Signed-off-by: noopur <noopur@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…urefederatedai#1501) * Initial changes for testing Signed-off-by: noopur <noopur@intel.com> * Initial changes for testing Signed-off-by: noopur <noopur@intel.com> * All workflows modified Signed-off-by: noopur <noopur@intel.com> * All workflows modified Signed-off-by: noopur <noopur@intel.com> * All workflows modified Signed-off-by: noopur <noopur@intel.com> * Correction of job name Signed-off-by: noopur <noopur@intel.com> * Correction of job name Signed-off-by: noopur <noopur@intel.com> * Testing one workflow Signed-off-by: noopur <noopur@intel.com> * Final set of changes Signed-off-by: noopur <noopur@intel.com> * Correct the repo URL Signed-off-by: noopur <noopur@intel.com> * Only commit related changes Signed-off-by: noopur <noopur@intel.com> * Correction in trufflehog job name Signed-off-by: noopur <noopur@intel.com> * Added commit_id to SSL wf after rebase Signed-off-by: noopur <noopur@intel.com> * Modified version file as well Signed-off-by: noopur <noopur@intel.com> * Make commit_id optional input Signed-off-by: noopur <noopur@intel.com> * Job name added for Trufflehog Signed-off-by: noopur <noopur@intel.com> --------- Signed-off-by: noopur <noopur@intel.com> Co-authored-by: Payal Chaurasiya <payal.chaurasiya@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
* added publications Signed-off-by: sarthakpati <sarthak.pati@hotmail.com> * added conda installation instructions Signed-off-by: sarthakpati <sarthak.pati@hotmail.com> --------- Signed-off-by: sarthakpati <sarthak.pati@hotmail.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.25.3 to 0.26.0. - [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases) - [Commits](pytest-dev/pytest-asyncio@v0.25.3...v0.26.0) --- updated-dependencies: - dependency-name: pytest-asyncio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Payal Chaurasiya <payal.chaurasiya@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
* add hippmapp3r Signed-off-by: porteratzo <omar.alfonso.montoya@hotmail.com> * addresed comments Signed-off-by: porteratzo <omar.alfonso.montoya@hotmail.com> * add reference Signed-off-by: porteratzo <omar.alfonso.montoya@hotmail.com> --------- Signed-off-by: porteratzo <omar.alfonso.montoya@hotmail.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
Signed-off-by: payalcha <payal.chaurasiya@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
securefederatedai#1514) * Run resiliency 3 times Signed-off-by: noopur <noopur@intel.com> * Run 50 rounds Signed-off-by: noopur <noopur@intel.com> * Extra debugging Signed-off-by: noopur <noopur@intel.com> * Extra debugging Signed-off-by: noopur <noopur@intel.com> * Testing Signed-off-by: noopur <noopur@intel.com> * Testing Signed-off-by: noopur <noopur@intel.com> * Modified Signed-off-by: noopur <noopur@intel.com> * Remove extra logging Signed-off-by: noopur <noopur@intel.com> * Remove extra logging Signed-off-by: noopur <noopur@intel.com> * Kill process as a one-liner Signed-off-by: noopur <noopur@intel.com> * Kill process as a one-liner Signed-off-by: noopur <noopur@intel.com> * Upgraded pytest from 8.3.4 to 8.3.5 Signed-off-by: noopur <noopur@intel.com> * Specific functions to fetch pids and kill processes Signed-off-by: noopur <noopur@intel.com> * Multiple changes done Signed-off-by: noopur <noopur@intel.com> * File changes as part of lint fixing Signed-off-by: noopur <noopur@intel.com> * Minor logging fixes and copyright year correction Signed-off-by: noopur <noopur@intel.com> * Review comments addressed Signed-off-by: noopur <noopur@intel.com> * Revert pytest version upgrade change Signed-off-by: noopur <noopur@intel.com> * Check if start_process is present Signed-off-by: noopur <noopur@intel.com> --------- Signed-off-by: noopur <noopur@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.4 to 8.3.5. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](pytest-dev/pytest@8.3.4...8.3.5) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Payal Chaurasiya <payal.chaurasiya@intel.com> Co-authored-by: Noopur <noopur@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…eratedai#1512) Bumps the github-actions group with 1 update: [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action). Updates `aquasecurity/trivy-action` from 0.29.0 to 0.30.0 - [Release notes](https://github.com/aquasecurity/trivy-action/releases) - [Commits](aquasecurity/trivy-action@0.29.0...0.30.0) --- updated-dependencies: - dependency-name: aquasecurity/trivy-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Payal Chaurasiya <payal.chaurasiya@intel.com> Co-authored-by: Akshay Pant <16561942+theakshaypant@users.noreply.github.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…#1517) * Change to add time taken for each round in metrics Signed-off-by: payalcha <payal.chaurasiya@intel.com> * Review comments Signed-off-by: payalcha <payal.chaurasiya@intel.com> --------- Signed-off-by: payalcha <payal.chaurasiya@intel.com> Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…comments update Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…orator Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
…lise Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
Signed-off-by: Pant, Akshay <akshay.akshaypant@gmail.com>
b1e6ec3 to
37c1055
Compare
37c1055 to
b9944a4
Compare
Summary
Moving serialisation/deserialisation logic out of collaborator into a separate middleware.
Why?
By clearly separating concerns across layers, it aims to enhance code readability for contributors and improves debuggability in case of failures.
This middleware introduction is similar to "middleware chaining" paradigm followed widely in Go where the same function is implemented across multiple "layers", each handling a distinct aspect of the functionality. In the context of this PR, this is done such that
Collaborator): Performs operations central to FL.CollaboratorSerialiser): Performs serialisation/desrialisation of numpy array.Type of Change (Mandatory)
Description (Mandatory)
TensorCodecto convert tensors to protobuf format and vice versa in order to communicate with the aggregator.Testing
Manual and CI.
Eden compression CI
Additional Information