From 6ec74ecaca984c31b6f9dfd35f10eaefaeb2ce09 Mon Sep 17 00:00:00 2001 From: jvmancuso Date: Mon, 27 Apr 2020 10:54:23 -0400 Subject: [PATCH 1/4] add tff aggregators placement rfc --- rfcs/20200427-tff-aggregators-placement.md | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 rfcs/20200427-tff-aggregators-placement.md diff --git a/rfcs/20200427-tff-aggregators-placement.md b/rfcs/20200427-tff-aggregators-placement.md new file mode 100644 index 000000000..032ebe77f --- /dev/null +++ b/rfcs/20200427-tff-aggregators-placement.md @@ -0,0 +1,91 @@ +# TF Federated Aggregators Placement + +| Status | (Proposed / Accepted / Implemented / Obsolete) | +:-------------- |:---------------------------------------------------- | +| **RFC #** | [TF Federated Aggregators Placement](https://github.com/tensorflow/community/pull/NNN) (TODO update when you have community PR #)| +| **Author(s)** | Jason Mancuso (jason@capeprivacy.com) | +| **Sponsor** | Michael Reneer (michaelreneer@google.com) | +| **Updated** | YYYY-MM-DD (TODO) | +| **Obsoletes** | TF-RFC it replaces, else remove this header | + +## Objective + +What are we doing and why? What problem will this solve? What are the goals and +non-goals? This is your executive summary; keep it short, elaborate below. +Add an explicit placement for Aggregators to the TensorFlow Federated Core. + +## Motivation + +Why this is a valuable problem to solve? What background information is needed +to show how this design addresses the problem? + +Which users are affected by the problem? Why is it a problem? What data supports +this? What related work exists? + +## User Benefit + +How will users (or other contributors) benefit from this work? What would be the +headline in the release notes or blog post? + +## Design Proposal + +This is the meat of the document, where you explain your proposal. If you have +multiple alternatives, be sure to use sub-sections for better separation of the +idea, and list pros/cons to each approach. If there are alternatives that you +have eliminated, you should also list those here, and explain why you believe +your chosen approach is superior. + +Make sure you’ve thought through and addressed the following sections. If a section is not relevant to your specific proposal, please explain why, e.g. your RFC addresses a convention or process, not an API. + + +### Alternatives Considered +* Make sure to discuss the relative merits of alternatives to your proposal. + +### Performance Implications +* Do you expect any (speed / memory)? How will you confirm? +* There should be microbenchmarks. Are there? +* There should be end-to-end tests and benchmarks. If there are not (since this is still a design), how will you track that these will be created? + +### Dependencies +* Dependencies: does this proposal add any new dependencies to TensorFlow? +* Dependent projects: are there other areas of TensorFlow or things that use TensorFlow (TFX/pipelines, TensorBoard, etc.) that this affects? How have you identified these dependencies and are you sure they are complete? If there are dependencies, how are you managing those changes? + +### Engineering Impact +* Do you expect changes to binary size / startup time / build time / test times? +* Who will maintain this code? Is this code in its own buildable unit? Can this code be tested in its own? Is visibility suitably restricted to only a small API surface for others to use? + +### Platforms and Environments +* Platforms: does this work on all platforms supported by TensorFlow? If not, why is that ok? Will it work on embedded/mobile? Does it impact automatic code generation or mobile stripping tooling? Will it work with transformation tools? +* Execution environments (Cloud services, accelerator hardware): what impact do you expect and how will you confirm? + +### Best Practices +* Does this proposal change best practices for some aspect of using/developing TensorFlow? How will these changes be communicated/enforced? + +### Tutorials and Examples +* If design changes existing API or creates new ones, the design owner should create end-to-end examples (ideally, a tutorial) which reflects how new feature will be used. Some things to consider related to the tutorial: + - The minimum requirements for this are to consider how this would be used in a Keras-based workflow, as well as a non-Keras (low-level) workflow. If either isn’t applicable, explain why. + - It should show the usage of the new feature in an end to end example (from data reading to serving, if applicable). Many new features have unexpected effects in parts far away from the place of change that can be found by running through an end-to-end example. TFX [Examples](https://github.com/tensorflow/tfx/tree/master/tfx/examples) have historically been good in identifying such unexpected side-effects and are as such one recommended path for testing things end-to-end. + - This should be written as if it is documentation of the new feature, i.e., consumable by a user, not a TensorFlow developer. + - The code does not need to work (since the feature is not implemented yet) but the expectation is that the code does work before the feature can be merged. + +### Compatibility +* Does the design conform to the backwards & forwards compatibility [requirements](https://www.tensorflow.org/programmers_guide/version_compat)? +* How will this proposal interact with other parts of the TensorFlow Ecosystem? + - How will it work with TFLite? + - How will it work with distribution strategies? + - How will it interact with tf.function? + - Will this work on GPU/TPU? + - How will it serialize to a SavedModel? + +### User Impact +* What are the user-facing changes? How will this feature be rolled out? + +## Detailed Design + +This section is optional. Elaborate on details if they’re important to +understanding the design, but would make it hard to read the proposal section +above. + +## Questions and Discussion Topics + +Seed this with open questions you require feedback on from the RFC process. From ecb43014936960f18b08c21bc3126b64bf107d82 Mon Sep 17 00:00:00 2001 From: jvmancuso Date: Wed, 29 Apr 2020 17:36:48 -0400 Subject: [PATCH 2/4] filling in some intro material --- rfcs/20200427-tff-aggregators-placement.md | 67 +++++++++++++++++----- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/rfcs/20200427-tff-aggregators-placement.md b/rfcs/20200427-tff-aggregators-placement.md index 032ebe77f..1e0da5b24 100644 --- a/rfcs/20200427-tff-aggregators-placement.md +++ b/rfcs/20200427-tff-aggregators-placement.md @@ -6,40 +6,79 @@ | **Author(s)** | Jason Mancuso (jason@capeprivacy.com) | | **Sponsor** | Michael Reneer (michaelreneer@google.com) | | **Updated** | YYYY-MM-DD (TODO) | -| **Obsoletes** | TF-RFC it replaces, else remove this header | ## Objective -What are we doing and why? What problem will this solve? What are the goals and -non-goals? This is your executive summary; keep it short, elaborate below. -Add an explicit placement for Aggregators to the TensorFlow Federated Core. +This document proposes adding an explicit `tff.AGGREGATORS` placement to the +Federated Core (FC) in TensorFlow Federated (TFF). This would allow users to express +custom aggregation protocols directly in TFF without adding unnecessary +assumptions about where aggregation functions must be placed and computed. ## Motivation -Why this is a valuable problem to solve? What background information is needed -to show how this design addresses the problem? - -Which users are affected by the problem? Why is it a problem? What data supports -this? What related work exists? +*Why this is a valuable problem to solve? What background information is needed +to show how this design addresses the problem?* + +When approaching federated learning with an eye for security or privacy, it is +useful to divide federated computation into two categories: computations performing +aggregations, and computations performing on-device computation. Security and +privacy issues tend to show up during the aggregation phase. This is particularly +clear when looking at common methods of adding security guarantees to traditional, +parameter-server style federated learning, for example with secure aggregation or +differentially private federated averaging (DP-FedAvg). + +In security-heightened settings, it is often worthwhile to separate computation +done in this aggregation phase from computation performed by the server in the +traditional parameter server setup. This amounts to delegating aggregations to a +third-party service. For example, when the clients are mistrustful of the server, +aggregations might be delegated to a trusted execution environment or to a cluster +of machines engaging in a secure multi-party computation protocol. Another example +is secure aggregation in the +[Encode-Shuffle-Analyze (ESA)](https://arxiv.org/abs/1710.00901) +model, which in a federated context generally assumes an additional +party to perform the secure shuffling needed to realize a differential privacy +guarantee. Since this is an established area of the literature with strong +motivations and results, we see this as an important line of work for TFF to +support in order to keep with its +[project goals](https://github.com/tensorflow/federated#tensorflow-federated). + +In general, any secure aggregation protocol can be represented as a coordinated +computation between three groups of parties: a server, a (potentially singleton) +set of aggregators, and a set of clients. Note that these need not be mutually +exclusive, so for example the traditional parameter server setting can be recovered +as a special case by treating the server as a singleton aggregators set. + +The TFF Federated Core (FC) language currently realizes logically-distinct parties +as "placements". While there exist `tff.SERVER` and `tff.CLIENTS` placements in FC, +there is no `tff.AGGREGATORS` placement. Without such a placement, implementing new +aggregation protocols in TFF can require low-level programming of the TFF executor +stacks, as evidenced by +[this community attempt to integrate secure aggregation](https://github.com/tf-encrypted/rfcs/blob/master/20190924-tensorflow-federated/integration-strategies.md). +By adding a `tff.AGGREGATORS` placement, users can more easily implement new +aggregation protocols by expressing them as federated computations in FC. ## User Benefit -How will users (or other contributors) benefit from this work? What would be the -headline in the release notes or blog post? +*How will users (or other contributors) benefit from this work? What would be the +headline in the release notes or blog post?* + +Users can now express custom aggregation protocols in the Federated Core by working +with federated data placed on `tff.AGGREGATORS`. Users will be unencumbered by the +constraints of the current federated types in FC. ## Design Proposal -This is the meat of the document, where you explain your proposal. If you have +*This is the meat of the document, where you explain your proposal. If you have multiple alternatives, be sure to use sub-sections for better separation of the idea, and list pros/cons to each approach. If there are alternatives that you have eliminated, you should also list those here, and explain why you believe your chosen approach is superior. -Make sure you’ve thought through and addressed the following sections. If a section is not relevant to your specific proposal, please explain why, e.g. your RFC addresses a convention or process, not an API. +Make sure you’ve thought through and addressed the following sections. If a section is not relevant to your specific proposal, please explain why, e.g. your RFC addresses a convention or process, not an API.* ### Alternatives Considered -* Make sure to discuss the relative merits of alternatives to your proposal. +A lower effort alternative might be to expect users to write custom executors, or custom executor stacks, to include additional "aggregator" parties when executing intrinisics. AGGREGATORS would stay outside of the FC type system, but could be sill be included in federated computations. This allows library designers to extend TFF for their own use cases. This is a major disadvantage, since users are only expected to be familiar with TFF Federated Learning (FL) or FC APIs, and this is a feature that would be useful to the majority of TFF users. ### Performance Implications * Do you expect any (speed / memory)? How will you confirm? From f8e688ffcfe3872bf366617bb977666ae55ef801 Mon Sep 17 00:00:00 2001 From: jvmancuso Date: Mon, 4 May 2020 17:17:59 -0400 Subject: [PATCH 3/4] initial draft complete --- rfcs/20200427-tff-aggregators-placement.md | 130 ---------------- rfcs/20200504-tff-aggregators-placement.md | 163 +++++++++++++++++++++ 2 files changed, 163 insertions(+), 130 deletions(-) delete mode 100644 rfcs/20200427-tff-aggregators-placement.md create mode 100644 rfcs/20200504-tff-aggregators-placement.md diff --git a/rfcs/20200427-tff-aggregators-placement.md b/rfcs/20200427-tff-aggregators-placement.md deleted file mode 100644 index 1e0da5b24..000000000 --- a/rfcs/20200427-tff-aggregators-placement.md +++ /dev/null @@ -1,130 +0,0 @@ -# TF Federated Aggregators Placement - -| Status | (Proposed / Accepted / Implemented / Obsolete) | -:-------------- |:---------------------------------------------------- | -| **RFC #** | [TF Federated Aggregators Placement](https://github.com/tensorflow/community/pull/NNN) (TODO update when you have community PR #)| -| **Author(s)** | Jason Mancuso (jason@capeprivacy.com) | -| **Sponsor** | Michael Reneer (michaelreneer@google.com) | -| **Updated** | YYYY-MM-DD (TODO) | - -## Objective - -This document proposes adding an explicit `tff.AGGREGATORS` placement to the -Federated Core (FC) in TensorFlow Federated (TFF). This would allow users to express -custom aggregation protocols directly in TFF without adding unnecessary -assumptions about where aggregation functions must be placed and computed. - -## Motivation - -*Why this is a valuable problem to solve? What background information is needed -to show how this design addresses the problem?* - -When approaching federated learning with an eye for security or privacy, it is -useful to divide federated computation into two categories: computations performing -aggregations, and computations performing on-device computation. Security and -privacy issues tend to show up during the aggregation phase. This is particularly -clear when looking at common methods of adding security guarantees to traditional, -parameter-server style federated learning, for example with secure aggregation or -differentially private federated averaging (DP-FedAvg). - -In security-heightened settings, it is often worthwhile to separate computation -done in this aggregation phase from computation performed by the server in the -traditional parameter server setup. This amounts to delegating aggregations to a -third-party service. For example, when the clients are mistrustful of the server, -aggregations might be delegated to a trusted execution environment or to a cluster -of machines engaging in a secure multi-party computation protocol. Another example -is secure aggregation in the -[Encode-Shuffle-Analyze (ESA)](https://arxiv.org/abs/1710.00901) -model, which in a federated context generally assumes an additional -party to perform the secure shuffling needed to realize a differential privacy -guarantee. Since this is an established area of the literature with strong -motivations and results, we see this as an important line of work for TFF to -support in order to keep with its -[project goals](https://github.com/tensorflow/federated#tensorflow-federated). - -In general, any secure aggregation protocol can be represented as a coordinated -computation between three groups of parties: a server, a (potentially singleton) -set of aggregators, and a set of clients. Note that these need not be mutually -exclusive, so for example the traditional parameter server setting can be recovered -as a special case by treating the server as a singleton aggregators set. - -The TFF Federated Core (FC) language currently realizes logically-distinct parties -as "placements". While there exist `tff.SERVER` and `tff.CLIENTS` placements in FC, -there is no `tff.AGGREGATORS` placement. Without such a placement, implementing new -aggregation protocols in TFF can require low-level programming of the TFF executor -stacks, as evidenced by -[this community attempt to integrate secure aggregation](https://github.com/tf-encrypted/rfcs/blob/master/20190924-tensorflow-federated/integration-strategies.md). -By adding a `tff.AGGREGATORS` placement, users can more easily implement new -aggregation protocols by expressing them as federated computations in FC. - -## User Benefit - -*How will users (or other contributors) benefit from this work? What would be the -headline in the release notes or blog post?* - -Users can now express custom aggregation protocols in the Federated Core by working -with federated data placed on `tff.AGGREGATORS`. Users will be unencumbered by the -constraints of the current federated types in FC. - -## Design Proposal - -*This is the meat of the document, where you explain your proposal. If you have -multiple alternatives, be sure to use sub-sections for better separation of the -idea, and list pros/cons to each approach. If there are alternatives that you -have eliminated, you should also list those here, and explain why you believe -your chosen approach is superior. - -Make sure you’ve thought through and addressed the following sections. If a section is not relevant to your specific proposal, please explain why, e.g. your RFC addresses a convention or process, not an API.* - - -### Alternatives Considered -A lower effort alternative might be to expect users to write custom executors, or custom executor stacks, to include additional "aggregator" parties when executing intrinisics. AGGREGATORS would stay outside of the FC type system, but could be sill be included in federated computations. This allows library designers to extend TFF for their own use cases. This is a major disadvantage, since users are only expected to be familiar with TFF Federated Learning (FL) or FC APIs, and this is a feature that would be useful to the majority of TFF users. - -### Performance Implications -* Do you expect any (speed / memory)? How will you confirm? -* There should be microbenchmarks. Are there? -* There should be end-to-end tests and benchmarks. If there are not (since this is still a design), how will you track that these will be created? - -### Dependencies -* Dependencies: does this proposal add any new dependencies to TensorFlow? -* Dependent projects: are there other areas of TensorFlow or things that use TensorFlow (TFX/pipelines, TensorBoard, etc.) that this affects? How have you identified these dependencies and are you sure they are complete? If there are dependencies, how are you managing those changes? - -### Engineering Impact -* Do you expect changes to binary size / startup time / build time / test times? -* Who will maintain this code? Is this code in its own buildable unit? Can this code be tested in its own? Is visibility suitably restricted to only a small API surface for others to use? - -### Platforms and Environments -* Platforms: does this work on all platforms supported by TensorFlow? If not, why is that ok? Will it work on embedded/mobile? Does it impact automatic code generation or mobile stripping tooling? Will it work with transformation tools? -* Execution environments (Cloud services, accelerator hardware): what impact do you expect and how will you confirm? - -### Best Practices -* Does this proposal change best practices for some aspect of using/developing TensorFlow? How will these changes be communicated/enforced? - -### Tutorials and Examples -* If design changes existing API or creates new ones, the design owner should create end-to-end examples (ideally, a tutorial) which reflects how new feature will be used. Some things to consider related to the tutorial: - - The minimum requirements for this are to consider how this would be used in a Keras-based workflow, as well as a non-Keras (low-level) workflow. If either isn’t applicable, explain why. - - It should show the usage of the new feature in an end to end example (from data reading to serving, if applicable). Many new features have unexpected effects in parts far away from the place of change that can be found by running through an end-to-end example. TFX [Examples](https://github.com/tensorflow/tfx/tree/master/tfx/examples) have historically been good in identifying such unexpected side-effects and are as such one recommended path for testing things end-to-end. - - This should be written as if it is documentation of the new feature, i.e., consumable by a user, not a TensorFlow developer. - - The code does not need to work (since the feature is not implemented yet) but the expectation is that the code does work before the feature can be merged. - -### Compatibility -* Does the design conform to the backwards & forwards compatibility [requirements](https://www.tensorflow.org/programmers_guide/version_compat)? -* How will this proposal interact with other parts of the TensorFlow Ecosystem? - - How will it work with TFLite? - - How will it work with distribution strategies? - - How will it interact with tf.function? - - Will this work on GPU/TPU? - - How will it serialize to a SavedModel? - -### User Impact -* What are the user-facing changes? How will this feature be rolled out? - -## Detailed Design - -This section is optional. Elaborate on details if they’re important to -understanding the design, but would make it hard to read the proposal section -above. - -## Questions and Discussion Topics - -Seed this with open questions you require feedback on from the RFC process. diff --git a/rfcs/20200504-tff-aggregators-placement.md b/rfcs/20200504-tff-aggregators-placement.md new file mode 100644 index 000000000..5f97e9bb2 --- /dev/null +++ b/rfcs/20200504-tff-aggregators-placement.md @@ -0,0 +1,163 @@ +# TF Federated Aggregators Placement + +| Status | (Proposed / Accepted / Implemented / Obsolete) | +:-------------- |:---------------------------------------------------- | +| **RFC #** | [TF Federated Aggregators Placement](https://github.com/tensorflow/community/pull/NNN) (TODO update when you have community PR #)| +| **Author(s)** | Jason Mancuso (jason@capeprivacy.com) | +| **Sponsor** | Michael Reneer (michaelreneer@google.com) | +| **Updated** | 2020-05-04 (TODO) | + +## Objective + +This document proposes adding an explicit `tff.AGGREGATORS` placement to the +Federated Core (FC) in TensorFlow Federated (TFF). This would allow users to express +custom aggregation protocols directly in TFF without adding unnecessary +assumptions about where aggregation functions must be placed and computed. + +## Motivation + +*Why this is a valuable problem to solve? What background information is needed +to show how this design addresses the problem?* + +When approaching federated learning with an eye for security or privacy, it is +useful to divide federated computation into two categories: computations performing +aggregations, and computations performing on-device computation. Security and +privacy issues tend to show up during the aggregation phase. This is particularly +clear when looking at common methods of adding security guarantees to traditional, +parameter-server style federated learning, for example with secure aggregation or +differentially private federated averaging (DP-FedAvg). + +In security-heightened settings, it is often worthwhile to separate computation +done in this aggregation phase from computation performed by the server in the +traditional parameter server setup. This amounts to delegating aggregations to a +third-party service. For example, when the clients are mistrustful of the server, +aggregations might be delegated to a trusted execution environment or to a cluster +of machines engaging in a secure multi-party computation protocol. Another example +is secure aggregation in the +[Encode-Shuffle-Analyze (ESA)](https://arxiv.org/abs/1710.00901) +model, which in a federated context generally assumes an additional +party to perform the secure shuffling needed to realize a differential privacy +guarantee. Since this is an established area of the literature with strong +motivations and results, we see this as an important line of work for TFF to +support in order to keep with its +[project goals](https://github.com/tensorflow/federated#tensorflow-federated). + +In general, any secure aggregation protocol can be represented as a coordinated +computation between three groups of parties: a server, a (potentially singleton) +set of aggregators, and a set of clients. Note that these need not be mutually +exclusive, so for example the traditional parameter server setting can be recovered +as a special case by treating the server as a singleton aggregators set. + +The TFF Federated Core (FC) language currently realizes logically-distinct parties +as "placements". While there exist `tff.SERVER` and `tff.CLIENTS` placements in FC, +there is no `tff.AGGREGATORS` placement. Without such a placement, implementing new +aggregation protocols in TFF can require low-level programming of the TFF executor +stacks, as evidenced by +[this community attempt to integrate secure aggregation](https://github.com/tf-encrypted/rfcs/blob/master/20190924-tensorflow-federated/integration-strategies.md). +By adding a new `tff.AGGREGATORS` placement, users can more easily implement new +aggregation protocols by expressing them as federated computations in FC. + +## User Benefit + +*How will users (or other contributors) benefit from this work? What would be the +headline in the release notes or blog post?* + +Users can now express custom aggregation protocols in the Federated Core by working +with federated data placed on `tff.AGGREGATORS`. Users will be unencumbered by the +constraints of the current federated types in FC. + +## Design Proposal + +*This is the meat of the document, where you explain your proposal. If you have +multiple alternatives, be sure to use sub-sections for better separation of the +idea, and list pros/cons to each approach. If there are alternatives that you +have eliminated, you should also list those here, and explain why you believe +your chosen approach is superior. + +Adding the `tff.AGGREGATORS` placement for federated types involves adding a new `Placement` and `PlacementLiteral`, and then extending the compiler to recognize federated values with this placement when computing intrinsics. The compiler generally defines separate intrinsics by placement; e.g., `tff.federated_value(value, placement)` is actually interpreted by the compiler as `federated_value_at_clients(value)` or `federated_value_at_server(value)`, depending on the provided `placement`. This means we we will want to add new intrinsics that correspond to `tff.AGGREGATORS`, e.g. `federated_value_at_aggregators`. + +Existing federated computation that will need modification fall into the two categories below: + +1. Intrinsics for federated computations that are already parameterized by placement. Note some of these functions don't have a `placement` arg in their public API signature, but internally correspond to different IntrinsicDefs based on placement of their federated input(s). + - `federated_eval` + - `federated_map` + - `federated_value` + - `federated_zip` + - `sequence_map` +2. Intrinsics that will need to be parameterized by placement, but currently aren't. + - `federated_aggregate` + - `federated_broadcast` + - `federated_collect` + - `federated_mean` + - `federated_reduce` + - `federated_secure_sum` + - `federated_sum` + - `sequence_reduce` + - `sequence_sum` + +Intrinsics in the latter category will likely need further discussion. This is because implementation details could change aspects of the underlying "federated algebra", like closure, or could introduce subtle semantic changes. + +As an example, assume we extend `federated_collect` to handle signatures of `T@CLIENTS -> T*@AGGREGATORS` and `T@AGGREGATORS -> T*@SERVER` (in addition to the current `CLIENTS -> SERVER`). If we want to maintain algebraic closure, we would extend `federated_broadcast` to handle `T@SERVER -> {T}@AGGREGATORS` and `T@AGGREGATORS -> {T}@CLIENTS`; similarly, we'd extend `sequence_reduce` to handle values of type `T@AGGREGATORS`. In this scenario, the new `federated_broadcast` would be a natural generalization of the old, however it's not clear if this kind of semantic change would be confusing to users of the FC. + +We hope this will be a good starting point for discussion. Ultimately, the RFC process should allow us to elaborate the exact type signatures that each of the new IntrinsicDefs should satisfy. + +### Alternatives Considered +A lower effort alternative might be to expect users to write custom executors, or custom executor stacks, to include additional "aggregator" parties when executing intrinisics. "AGGREGATORS" would stay outside of the FC type system, but could still be included in federated computations. This might allow library designers to extend TFF for their own use cases, but hinders the majority of TFF users who are not expected to learn the executor API. + +We also briefly considered the name `tff.AGGREGATOR` instead of `tff.AGGREGATORS`. We decided on the latter for two reasons: +1. `tff.AGGREGATOR` does not capture the possibility of multiple executor stacks coordinating aggregation (the existing `ComposingExecutor` qualifies as one such case). +2. `tff.AGGREGATOR` is equivalent to a singleton `tff.AGGREGATORS`. + +### Performance Implications +This is an additive improvement to the FC, so there should be no performance implications for existing functionality. TFF is designed to support this kind of addition with minimal overhead. New functionality could be less performant relative to current practices, but only from overhead inherent to adding a new node to a distributed computation. + +### Dependencies +This change brings no new dependencies. Since this proposal adds a new federated type, any project that enforces limits based on the current federated types may have to be updated. We will work with the TFF team to identify any affected projects and limit any breaking changes. + +### Engineering Impact +This code will likely bring marginal increases to build and test time, but changes to binary size should be negligible. Executor factories including a stack for the `tff.AGGREGATORS` placement will experience a nontrivial increase in startup time, but not all executor factories will need to include a stack for this placement. + +The code for this change will be mixed into existing modules in the TF Federated core. Since it affects the type system used by the TFF compiler and requires that relevant intrinsic definitions be modified to recognize a new placement, it will touch many different places in the TFF stack. Those who already own and maintain those code units will maintain and improve the change in the future, which makes their feedback critical throughout design and implementation. + +### Best Practices +The new `Placement` for federated types brings an addition to the Federated Core, which will be communicated in the TFF API documentation. This will only be relevant for users of the lower-level Federated Core, at least until a higher level API is included that relies on it. Below, we detail how this change should be communicated by existing tutorials. + +### Tutorials and Examples +Since this is a modification of an existing API, it likely does not warrant a new tutorial. We instead suggest modifying the existing [Part 1 Federated Core tutorial (FC 1)](https://www.tensorflow.org/federated/tutorials/custom_federated_algorithms_1) to include one or more federated computations that operate on Aggregator-placed data. We also considered modifying part 2 of the FC tutorial, but decided against that due to its stated goals. + +Concretely, we recommend two modifications to the FC 1 tutorial: +- In the "Placement" section, the discussion will need to include the `tff.AGGREGATORS` placement. This section should stress that the placement can be considered optional, whereas the others (`tff.CLIENTS`, `tff.SERVER`) are strictly necessary for most interesting federated computations. +- In the "Composing Federated Computations" section, we recommend adding a short sub-section or paragraph that describes how one might refactor the `get_average_temperature` function to perform its `federated_mean` with a placement of `tff.AGGREGATORS`. We include short and long form examples below for consideration. + +```python +# short form +@tff.federated_computation(tff.FederatedType(tf.float32, tff.CLIENTS)) +def get_average_temperature(sensor_readings): + averaged_temp = tff.federated_mean(sensor_readings, placement=tff.AGGREGATORS) + return tff.federated_collect(averaged_temp, placement=tff.SERVER) + +# long form +@tff.federated_computation(tff.FederatedType(tf.float32, tff.CLIENTS)) +def get_average_temperature(sensor_readings): + collected_readings = tff.federated_collect(sensor_readings, placement=tff.AGGREGATORS) + num_clients = len(collected_readings) + total_temp = tff.sequence_sum(collected_readings) + return tff.federated_map(lambda x: x / num_clients, total_temp) +``` + +### Compatibility +* Does the design conform to the backwards & forwards compatibility [requirements](https://www.tensorflow.org/programmers_guide/version_compat)? + +Since this design adds new functionality, it would change the public API. While TFF is still pre-1.0, it does not yet explicitly guarantee backwards compatibility of its public API. Nevertheless, we can hope to limit impact on the public API through judicious use of default keyword arguments. + +Concretely, we can maintain backwards compatibility for federated computations that gain a `placement` keyword argument by defaulting that argument to `tff.SERVER`. We recommend _judicious_ use because there may be instances where a change in semantic justifies a breaking change. These should be taken on a case-by-case basis, and we hope to clearly define and justify any breaking changes that might arise. + +This design does not significantly impact compatibility with the rest of the TF ecosystem. + +## Questions and Discussion Topics + +- Which of the intrinsics above should actually be modified/parameterized? +- How strict should we be about algebraic closure in the federated type system? There could be an argument against, e.g. if we want to limit which intrinsics can ever involve `tff.AGGREGATORS`. +- Are the existing tutorial changes sufficient? What is the best way to communicate these changes in existing documentation? +- What should the implementation/release strategy be? Should this wait until TFF 1.x.x? +- Once changes to current intrinsics have been planned, what qualifies as a "judicious" use of defaults for maintaining backwards compatiblity? \ No newline at end of file From 4cde7e8df4f96f05120eb69f17715075244b61bf Mon Sep 17 00:00:00 2001 From: jvmancuso Date: Mon, 4 May 2020 18:48:04 -0400 Subject: [PATCH 4/4] cleanup --- rfcs/20200504-tff-aggregators-placement.md | 161 ++++++++++++++------- 1 file changed, 112 insertions(+), 49 deletions(-) diff --git a/rfcs/20200504-tff-aggregators-placement.md b/rfcs/20200504-tff-aggregators-placement.md index 5f97e9bb2..a93261206 100644 --- a/rfcs/20200504-tff-aggregators-placement.md +++ b/rfcs/20200504-tff-aggregators-placement.md @@ -1,24 +1,21 @@ # TF Federated Aggregators Placement -| Status | (Proposed / Accepted / Implemented / Obsolete) | +| Status | Proposed | :-------------- |:---------------------------------------------------- | -| **RFC #** | [TF Federated Aggregators Placement](https://github.com/tensorflow/community/pull/NNN) (TODO update when you have community PR #)| +| **RFC #** | https://github.com/tensorflow/community/pull/TODO | | **Author(s)** | Jason Mancuso (jason@capeprivacy.com) | | **Sponsor** | Michael Reneer (michaelreneer@google.com) | -| **Updated** | 2020-05-04 (TODO) | +| **Updated** | 2020-05-04 | ## Objective -This document proposes adding an explicit `tff.AGGREGATORS` placement to the -Federated Core (FC) in TensorFlow Federated (TFF). This would allow users to express -custom aggregation protocols directly in TFF without adding unnecessary -assumptions about where aggregation functions must be placed and computed. +This document proposes adding a `tff.AGGREGATORS` placement to the Federated Core +(FC) in TensorFlow Federated (TFF). This would lift the requirement that all +aggregations be computed on `tff.SERVER` while still allowing users to express +custom aggregation logic using FC & TF. ## Motivation -*Why this is a valuable problem to solve? What background information is needed -to show how this design addresses the problem?* - When approaching federated learning with an eye for security or privacy, it is useful to divide federated computation into two categories: computations performing aggregations, and computations performing on-device computation. Security and @@ -59,32 +56,36 @@ aggregation protocols by expressing them as federated computations in FC. ## User Benefit -*How will users (or other contributors) benefit from this work? What would be the -headline in the release notes or blog post?* - Users can now express custom aggregation protocols in the Federated Core by working with federated data placed on `tff.AGGREGATORS`. Users will be unencumbered by the constraints of the current federated types in FC. ## Design Proposal -*This is the meat of the document, where you explain your proposal. If you have -multiple alternatives, be sure to use sub-sections for better separation of the -idea, and list pros/cons to each approach. If there are alternatives that you -have eliminated, you should also list those here, and explain why you believe -your chosen approach is superior. - -Adding the `tff.AGGREGATORS` placement for federated types involves adding a new `Placement` and `PlacementLiteral`, and then extending the compiler to recognize federated values with this placement when computing intrinsics. The compiler generally defines separate intrinsics by placement; e.g., `tff.federated_value(value, placement)` is actually interpreted by the compiler as `federated_value_at_clients(value)` or `federated_value_at_server(value)`, depending on the provided `placement`. This means we we will want to add new intrinsics that correspond to `tff.AGGREGATORS`, e.g. `federated_value_at_aggregators`. - -Existing federated computation that will need modification fall into the two categories below: - -1. Intrinsics for federated computations that are already parameterized by placement. Note some of these functions don't have a `placement` arg in their public API signature, but internally correspond to different IntrinsicDefs based on placement of their federated input(s). +Adding the `tff.AGGREGATORS` placement for federated types involves adding a new +`Placement` and `PlacementLiteral`, and then extending the compiler to recognize +federated values with this placement when computing intrinsics. The compiler +generally defines separate intrinsics by placement; e.g. +`tff.federated_value(value, placement)` is actually interpreted by the compiler as +`federated_value_at_clients(value)` or `federated_value_at_server(value)`, +depending on the provided `placement`. This means we we will want to add new +intrinsics that correspond to `tff.AGGREGATORS`, e.g. +`federated_value_at_aggregators`. + +Existing federated computation that will need modification fall into the two +categories below: + +1. Intrinsics for federated computations that are already parameterized by +placement. Note some of these functions don't have a `placement` arg in their +public API signature, but internally correspond to different IntrinsicDefs based on +placement of their federated input(s). - `federated_eval` - `federated_map` - `federated_value` - `federated_zip` - `sequence_map` -2. Intrinsics that will need to be parameterized by placement, but currently aren't. +2. Intrinsics that will need to be parameterized by placement, but currently +aren't. - `federated_aggregate` - `federated_broadcast` - `federated_collect` @@ -95,39 +96,89 @@ Existing federated computation that will need modification fall into the two cat - `sequence_reduce` - `sequence_sum` -Intrinsics in the latter category will likely need further discussion. This is because implementation details could change aspects of the underlying "federated algebra", like closure, or could introduce subtle semantic changes. +Intrinsics in the latter category will likely need further discussion. This is +because implementation details could change aspects of the underlying "federated +algebra", like closure, or could introduce subtle semantic changes. -As an example, assume we extend `federated_collect` to handle signatures of `T@CLIENTS -> T*@AGGREGATORS` and `T@AGGREGATORS -> T*@SERVER` (in addition to the current `CLIENTS -> SERVER`). If we want to maintain algebraic closure, we would extend `federated_broadcast` to handle `T@SERVER -> {T}@AGGREGATORS` and `T@AGGREGATORS -> {T}@CLIENTS`; similarly, we'd extend `sequence_reduce` to handle values of type `T@AGGREGATORS`. In this scenario, the new `federated_broadcast` would be a natural generalization of the old, however it's not clear if this kind of semantic change would be confusing to users of the FC. +As an example, assume we extend `federated_collect` to handle signatures of +`T@CLIENTS -> T*@AGGREGATORS` and `T@AGGREGATORS -> T*@SERVER` (in addition to the +current `CLIENTS -> SERVER`). If we want to maintain algebraic closure, we would +extend `federated_broadcast` to handle `T@SERVER -> {T}@AGGREGATORS` and +`T@AGGREGATORS -> {T}@CLIENTS`; similarly, we would extend `sequence_reduce` to +handle values of type `T@AGGREGATORS`. In this scenario, the new +`federated_broadcast` would be a natural generalization of the old, however it's +not clear if this kind of semantic change would be confusing to users of the FC. -We hope this will be a good starting point for discussion. Ultimately, the RFC process should allow us to elaborate the exact type signatures that each of the new IntrinsicDefs should satisfy. +We hope this will be a good starting point for discussion. Ultimately, the RFC +process should allow us to elaborate the exact type signatures that each of the new +IntrinsicDefs should satisfy. ### Alternatives Considered -A lower effort alternative might be to expect users to write custom executors, or custom executor stacks, to include additional "aggregator" parties when executing intrinisics. "AGGREGATORS" would stay outside of the FC type system, but could still be included in federated computations. This might allow library designers to extend TFF for their own use cases, but hinders the majority of TFF users who are not expected to learn the executor API. - -We also briefly considered the name `tff.AGGREGATOR` instead of `tff.AGGREGATORS`. We decided on the latter for two reasons: -1. `tff.AGGREGATOR` does not capture the possibility of multiple executor stacks coordinating aggregation (the existing `ComposingExecutor` qualifies as one such case). +A lower effort alternative might be to expect users to write custom executors, or +custom executor stacks, to include additional "aggregator" parties when executing +intrinisics. "AGGREGATORS" would stay outside of the FC type system, but could +still be included in federated computations. This might allow library designers to +extend TFF for their own use cases, but hinders the majority of TFF users who are +not expected to learn the executor API. + +We also briefly considered the name `tff.AGGREGATOR` instead of `tff.AGGREGATORS`. +We decided on the latter for two reasons: +1. `tff.AGGREGATOR` does not capture the possibility of multiple executor stacks +coordinating aggregation (the existing `ComposingExecutor` qualifies as one such +case). 2. `tff.AGGREGATOR` is equivalent to a singleton `tff.AGGREGATORS`. ### Performance Implications -This is an additive improvement to the FC, so there should be no performance implications for existing functionality. TFF is designed to support this kind of addition with minimal overhead. New functionality could be less performant relative to current practices, but only from overhead inherent to adding a new node to a distributed computation. +This is an additive improvement to the FC, so there should be no performance +implications for existing functionality. TFF is designed to support this kind of +addition with minimal overhead. New functionality could be less performant relative +to current practices, but only from overhead inherent to adding a new node to a +distributed computation. ### Dependencies -This change brings no new dependencies. Since this proposal adds a new federated type, any project that enforces limits based on the current federated types may have to be updated. We will work with the TFF team to identify any affected projects and limit any breaking changes. +This change brings no new dependencies. Since this proposal adds a new federated +type, any project that enforces limits based on the current federated types may +have to be updated. We will work with the TFF team to identify any affected +projects and limit any breaking changes. ### Engineering Impact -This code will likely bring marginal increases to build and test time, but changes to binary size should be negligible. Executor factories including a stack for the `tff.AGGREGATORS` placement will experience a nontrivial increase in startup time, but not all executor factories will need to include a stack for this placement. - -The code for this change will be mixed into existing modules in the TF Federated core. Since it affects the type system used by the TFF compiler and requires that relevant intrinsic definitions be modified to recognize a new placement, it will touch many different places in the TFF stack. Those who already own and maintain those code units will maintain and improve the change in the future, which makes their feedback critical throughout design and implementation. +This code will likely bring marginal increases to build and test time, but changes +to binary size should be negligible. Executor factories including a stack for the +`tff.AGGREGATORS` placement will experience a nontrivial increase in startup time, +but not all executor factories will need to include a stack for this placement. + +The code for this change will be mixed into existing modules in the TF Federated +core. Since it affects the type system used by the TFF compiler and requires that +relevant intrinsic definitions be modified to recognize a new placement, it will +touch many different places in the TFF stack. Those who already own and maintain +those code units will maintain and improve the change in the future, which makes +their feedback critical throughout design and implementation. ### Best Practices -The new `Placement` for federated types brings an addition to the Federated Core, which will be communicated in the TFF API documentation. This will only be relevant for users of the lower-level Federated Core, at least until a higher level API is included that relies on it. Below, we detail how this change should be communicated by existing tutorials. +The new `Placement` for federated types brings an addition to the Federated Core, +which will be communicated in the TFF API documentation. This will only be relevant +for users of the lower-level Federated Core, at least until a higher level API is +included that relies on it. Below, we detail how this change should be communicated +by existing tutorials. ### Tutorials and Examples -Since this is a modification of an existing API, it likely does not warrant a new tutorial. We instead suggest modifying the existing [Part 1 Federated Core tutorial (FC 1)](https://www.tensorflow.org/federated/tutorials/custom_federated_algorithms_1) to include one or more federated computations that operate on Aggregator-placed data. We also considered modifying part 2 of the FC tutorial, but decided against that due to its stated goals. +Since this is a modification of an existing API, it likely does not warrant a new +tutorial. We instead suggest modifying the existing +[Part 1 Federated Core tutorial (FC 1)](https://www.tensorflow.org/federated/tutorials/custom_federated_algorithms_1) +to include one or more federated computations that operate on Aggregator-placed +data. We also considered modifying part 2 of the FC tutorial, but decided against +that due to its stated goals. Concretely, we recommend two modifications to the FC 1 tutorial: -- In the "Placement" section, the discussion will need to include the `tff.AGGREGATORS` placement. This section should stress that the placement can be considered optional, whereas the others (`tff.CLIENTS`, `tff.SERVER`) are strictly necessary for most interesting federated computations. -- In the "Composing Federated Computations" section, we recommend adding a short sub-section or paragraph that describes how one might refactor the `get_average_temperature` function to perform its `federated_mean` with a placement of `tff.AGGREGATORS`. We include short and long form examples below for consideration. +- In the "Placement" section, the discussion will need to include the +`tff.AGGREGATORS` placement. This section should stress that the placement can be +considered optional, whereas the others (`tff.CLIENTS`, `tff.SERVER`) are strictly +necessary for most interesting federated computations. +- In the "Composing Federated Computations" section, we recommend adding a short +sub-section or paragraph that describes how one might refactor the +`get_average_temperature` function to perform its `federated_mean` with a placement +of `tff.AGGREGATORS`. We include short and long form examples below for +consideration. ```python # short form @@ -146,18 +197,30 @@ def get_average_temperature(sensor_readings): ``` ### Compatibility -* Does the design conform to the backwards & forwards compatibility [requirements](https://www.tensorflow.org/programmers_guide/version_compat)? -Since this design adds new functionality, it would change the public API. While TFF is still pre-1.0, it does not yet explicitly guarantee backwards compatibility of its public API. Nevertheless, we can hope to limit impact on the public API through judicious use of default keyword arguments. +Since this design adds new functionality, it would change the public API. While TFF +is still pre-1.0, it does not yet explicitly guarantee backwards compatibility of +its public API. Nevertheless, we can hope to limit impact on the public API through +judicious use of default keyword arguments. -Concretely, we can maintain backwards compatibility for federated computations that gain a `placement` keyword argument by defaulting that argument to `tff.SERVER`. We recommend _judicious_ use because there may be instances where a change in semantic justifies a breaking change. These should be taken on a case-by-case basis, and we hope to clearly define and justify any breaking changes that might arise. +Concretely, we can maintain backwards compatibility for federated computations that +gain a `placement` keyword argument by defaulting that argument to `tff.SERVER`. We +recommend _judicious_ use because there may be instances where a change in semantic +justifies a breaking change. These should be taken on a case-by-case basis, and we +hope to clearly define and justify any breaking changes that might arise. -This design does not significantly impact compatibility with the rest of the TF ecosystem. +This design does not significantly impact compatibility with the rest of the TF +ecosystem. ## Questions and Discussion Topics - Which of the intrinsics above should actually be modified/parameterized? -- How strict should we be about algebraic closure in the federated type system? There could be an argument against, e.g. if we want to limit which intrinsics can ever involve `tff.AGGREGATORS`. -- Are the existing tutorial changes sufficient? What is the best way to communicate these changes in existing documentation? -- What should the implementation/release strategy be? Should this wait until TFF 1.x.x? -- Once changes to current intrinsics have been planned, what qualifies as a "judicious" use of defaults for maintaining backwards compatiblity? \ No newline at end of file +- How strict should we be about algebraic closure in the federated type system? +There could be an argument against, e.g. if we want to limit which intrinsics can +ever involve `tff.AGGREGATORS`. +- Are the existing tutorial changes sufficient? What is the best way to communicate +these changes in existing documentation? +- What should the implementation/release strategy be? Should this wait until TFF +1.x.x? +- Once changes to current intrinsics have been planned, what qualifies as a +"judicious" use of defaults for maintaining backwards compatiblity?