Package: rayfed-nightly
RayFedA multiple parties joint, distributed execution engine based on Ray, to help build your own federated learning frameworks in minutes.OverviewNote: This project is now in actively developing.RayFed is a distributed computing framework for cross-parties federated learning.
Built in the Ray ecosystem, RayFed provides a Ray native programming pattern for federated learning so that users can build a distributed program easily.It provides users the role of "party", thus users can write code belonging to the specific party explicitly imposing more clear data perimeters. These codes will be restricted to execute within the party.As for the code execution, RayFed introduces the multi-controller architecture:
The code view in each party is exactly the same, but the execution differs based on the declared party of code and the current party of executor.FeaturesRay Native Programming PatternLet you write your federated and distributed computing applications like a single-machine program.Multiple Controller Execution ModeThe RayFed job can be run in the single-controller mode for developing and debugging and the multiple-controller mode for production without code change.Very Restricted and Clear Data PerimetersBecause of the PUSH-BASED data transferring mechanism and multiple controller execution mode, the data transmission authority is held by the data owner rather than the data demander.Very Large Scale Federated Computing and TrainingPowered by the scalabilities and the distributed abilities from Ray, large scale federated computing and training jobs are naturally supported.Supported Ray VersionsRayFed Versionsray-1.13.0ray-2.4.0ray-2.5.1ray-2.6.3ray-2.7.1ray-2.8.1ray-2.9.00.1.0✅✅✅✅✅✅✅0.2.0not releasednot releasednot releasednot releasednot releasednot releasednot releasedInstallationInstall it from pypi.pipinstall-UrayfedInstall the nightly released version from pypi.pipinstall-Urayfed-nightlyQuick StartThis example shows how to aggregate values across two participators.Step 1: Write an Actor that Generates ValueTheMyActorincrement its value bynum.
This actor will be executed within the explicitly declared party.importsysimportrayimportfed@fed.remoteclassMyActor:def__init__(self,value):self.value=valuedefinc(self,num):self.value=self.value+numreturnself.valueStep 2: Define Aggregation FunctionThe below function collects and aggragates values from two parties separately, and will also be executed within the declared party.@fed.remotedefaggregate(val1,val2):returnval1+val2Step 3: Create the actor and call methods in a specific partyThe creation code is similar withRay, however, the difference is that inRayFedthe actor must be explicitly created within a party:actor_alice=MyActor.party("alice").remote(1)actor_bob=MyActor.party("bob").remote(1)val_alice=actor_alice.inc.remote(1)val_bob=actor_bob.inc.remote(2)sum_val_obj=aggregate.party("bob").remote(val_alice,val_bob)The above codes:Create twoMyActors separately in each party, i.e. 'alice' and 'bob';Increment by '1' in alice and '2' in 'bob';Execute the aggregation function in party 'bob'.Step 4: Declare Cross-party Cluster & Initdefmain(party):ray.init(address='local',include_dashboard=False)addresses={'alice':'127.0.0.1:11012','bob':'127.0.0.1:11011',}fed.init(addresses=addresses,party=party)This first declares a two-party cluster, whose addresses corresponding to '127.0.0.1:11012' in 'alice' and '127.0.0.1:11011' in 'bob'.
And then, thefed.initcreate a cluster in the specified party.
Note thatfed.initshould be called twice, passing in the different party each time.When executing codes in step 1~3, the 'alice' cluster will only execute functions whose "party" are also declared as 'alice'.Put it together !Save below codes asdemo.py:importsysimportrayimportfed@fed.remoteclassMyActor:def__init__(self,value):self.value=valuedefinc(self,num):self.value=self.value+numreturnself.value@fed.remotedefaggregate(val1,val2):returnval1+val2defmain(party):ray.init(address='local',include_dashboard=False)addresses={'alice':'127.0.0.1:11012','bob':'127.0.0.1:11011',}fed.init(addresses=addresses,party=party)actor_alice=MyActor.party("alice").remote(1)actor_bob=MyActor.party("bob").remote(1)val_alice=actor_alice.inc.remote(1)val_bob=actor_bob.inc.remote(2)sum_val_obj=aggregate.party("bob").remote(val_alice,val_bob)result=fed.get(sum_val_obj)print(f"The result in party{party}is{result}")fed.shutdown()ray.shutdown()if__name__=="__main__":assertlen(sys.argv)==2,'Please run this script with party.'main(sys.argv[1])Run The Code.Open a terminal and run the code asalice. It's recommended to run the code with Ray TLS enabled (please refer toRay TLS)RAY_USE_TLS=1\RAY_TLS_SERVER_CERT='/path/to/the/server/cert/file'\RAY_TLS_SERVER_KEY='/path/to/the/server/key/file'\RAY_TLS_CA_CERT='/path/to/the/ca/cert/file'\pythontest.pyaliceIn the mean time, open another terminal and run the code asbob.RAY_USE_TLS=1\RAY_TLS_SERVER_CERT='/path/to/the/server/cert/file'\RAY_TLS_SERVER_KEY='/path/to/the/server/key/file'\RAY_TLS_CA_CERT='/path/to/the/ca/cert/file'\pythontest.pybobThen you will getThe result in party alice is 5on the first terminal screen andThe result in party bob is 5on the second terminal screen.Figure shows the execution under the hood:## Running untrusted codes
As a general rule: Always execute untrusted codes inside a sandbox (e.g., [nsjail](https://github.com/google/nsjail)).Who use us