Home

Awesome

<img src="art/fake-logo.png" alt="syft.js logo" width="200" />

Build codecov npm GitHub OpenCollective

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

All Contributors

<!-- ALL-CONTRIBUTORS-BADGE:END -->

Syft.js

Syft.js is the “web” part of the OpenMined's open-source ecosystem for federated learning, which currently spans across web, iOS, Android, and servers/IoT.

Syft.js has following core features:

The library is built on top of TensorFlow.js.

There are a variety of additional privacy-preserving protections that may be applied, including differential privacy, muliti-party computation, and secure aggregation.

If you want to know how scalable federated systems are built, Towards Federated Learning at Scale is a fantastic introduction!

Installation

Note that syft.js needs Tensorflow.js library as peer dependency.

If you're using a package manager like NPM:

npm install --save @openmined/syft.js @tensorflow/tfjs-core

Or if Yarn is your cup of tea:

yarn add @openmined/syft.js @tensorflow/tfjs-core

If you're not using a package manager, you will be able to include Syft.js within a <script> tag. In this case library classes will be available under syft global object.

<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.2.5/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@openmined/syft.js@latest/dist/index.js"></script>

<script type="text/javascript">
  // Create syft worker
  const worker = syft.Syft({...});
  ...
</script>

Quick Start

As a developer, there are few steps to building your own secure federated learning system upon the OpenMined infrastructure:

  1. :robot: Develop ML model and training procedure (aka Plan in PySyft terminology) using PySyft.
  2. :earth_americas: Host model and Plans on PyGrid, which will deal with all the federated learning components of your pipeline.
  3. :tada: Execute the training on the variety of end-user devices using the client library (syft.js, SwiftSyft, KotlinSyft, PySyft).
  4. :lock: Securely aggregate trained user models in PyGrid.

:notebook: The entire workflow and process is described in greater detail in the Web & Mobile Federated Learning project roadmap.

Syft.js provides minimalistic API to communicate with federated learning PyGrid endpoints and execute PySyft's Plans in a browser. The federated learning cycle implemented with syft.js would contain following steps:

This whole cycle can be expressed in the following code:

import * as tf from '@tensorflow/tfjs-core';
import { Syft } from '@openmined/syft.js';

const gridUrl = 'ws://pygrid.myserver.com:5000';
const modelName = 'my-model';
const modelVersion = '1.0.0';

// if the model is protected with authentication token (optional)
const authToken = '...';

const worker = new Syft({ gridUrl, authToken, verbose: true });
const job = await worker.newJob({ modelName, modelVersion });
job.start();

job.on('accepted', async ({ model, clientConfig }) => {
  const batchSize = clientConfig.batch_size;
  const lr = clientConfig.lr;

  // Load data.
  const batches = LOAD_DATA(batchSize);

  // Load model parameters.
  let modelParams = model.params.map((p) => p.clone());

  // Main training loop.
  for (let [data, labels] of batches) {
    // NOTE: this is just one possible example.
    // Plan name (e.g. 'training_plan'), its input arguments and outputs depends on FL configuration and actual Plan implementation.
    let updatedModelParams = await job.plans['training_plan'].execute(
      job.worker,
      data,
      labels,
      batchSize,
      lr,
      ...modelParams
    );

    // Use updated model params in the next iteration.
    for (let i = 0; i < modelParams.length; i++) {
      modelParams[i].dispose();
      modelParams[i] = updatedModelParams[i];
    }
  }

  // Calculate & send model diff.
  const modelDiff = await model.createSerializedDiff(modelParams);
  await job.report(modelDiff);
});

job.on('rejected', ({ timeout }) => {
  // Handle the job rejection, e.g. re-try after timeout.
});

job.on('error', (err) => {
  // Handle errors.
});

Note that syft.js doesn't handle user's data collection, data storage and loading.

API Documentation

See API Documentation for complete reference.

Running the Demo App

The “Hello World” syft.js demo is MNIST training example located in examples/mnist folder. It demonstrates how a simple neural net model created in PySyft can be trained in a browser and the result of training averaged from multiple federated learning participants.

<img src="art/mnist-demo-ani.gif" alt="syft.js MNIST demo animation" />

Running the demo is multi-stage and multi-component process (as the federated learning itself).

Below are example instructions that assume you want to put everything under ~/fl-demo folder.

Installation

It is recommended that you install python packages in separate virtualenv or conda environment, e.g.:

virtualenv -p python3 syft
source syft/bin/activate

or

conda create -n syft python=3.7
conda activate syft

Now, you will need to install following packages:

Seeding the Model & Plan

Syft.js connects to PyGrid to pick up the model and training Plan. For the demo to work, we need to populate that data into PyGrid.

Run PyGrid

There're two possible ways to start PyGrid:

Here we assume you don't need to change default PyGrid configuration and it listens on the localhost:5000. If you need to use different host/port, PyGrid URL will need to be adjusted accordingly in further steps.

Create Model & Plan

After PyGrid is running, the next step is to create the model and training plan and host them in PyGrid. PySyft tutorials include MNIST example jupyter notebooks that guide you through this process.

Fire up jupyter notebook in PySyft root folder:

cd ~/fl-demo/PySyft
jupyter notebook --notebook-dir=$(pwd)

In the console, you should see URL you should open, or the browser will open automatically. After this, navigate to examples/tutorials/model-centric-fl and run the first notebook. At this point, you can pull down the model and training plan with syft.js. However, if you'd like to see how to execute the plan using the PySyft FL worker, try running the second notebook.

PyGrid Clean-up

In case you need to reset PyGrid database to blank state, stop the process with Ctrl+C and remove databaseGateway.db file in PyGrid. Or, if you used docker-compose, stop and re-start it using docker-compose up --force-recreate command.

Starting the Demo

Finally, we got to the browser part of the demo:

cd ~/fl-demo/syft.js/examples/mnist
npm start

This should start development server and open localhost:8080 in the browser. Assuming PyGrid URL, MNIST model name and version were not modified in previous steps, just press “Start FL Worker”.

You should see following in dev console:

If “Keep making cycle requests” is checked, the whole cycle process is repeated until PyGrid tells worker that model training is complete.

Compatibility

PySyft

Syft.js has been tested with PySyft 0.2.7

PyGrid

Syft.js has been tested with the latest version of PyGrid on master.

Tensorflow.js

Syft.js was tested with Tensorflow.js v1.2.5.

Browser Support

Syft.js was tested with Chrome and Firefox browsers.

Support

For support in using this library, please join the #lib_syft_js Slack channel. If you’d like to follow along with any code changes to the library, please join the #code_syftjs Slack channel. Click here to join our Slack community!

Contributing

Please check open issues as a starting point.

Bug reports and feature suggestions are welcomed as well.

The workflow is usual for github, the master branch is considered stable:

  1. Star, fork, and clone the repo.
  2. Create new branch for your changes.
  3. Push changes in your fork.
  4. Submit a PR to OpenMined/syft.js.
  5. PR is reviewed and accepted.

Read the contribution guide as a good starting place. Additionally, we welcome you to the slack for queries related to the library and contribution in general. The Slack channel #lib_syft_js is specific to syft.js development. See you there!

Contributors

These people were integral part of the efforts to bring syft.js to fruition and in its active development.

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> <!-- prettier-ignore-start --> <!-- markdownlint-disable --> <table> <tr> <td align="center"><a href="https://www.patrickcason.com"><img src="https://avatars1.githubusercontent.com/u/1297930?v=4" width="100px;" alt=""/><br /><sub><b>Patrick Cason</b></sub></a><br /><a href="#ideas-cereallarceny" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/OpenMined/syft.js/commits?author=cereallarceny" title="Code">💻</a> <a href="#design-cereallarceny" title="Design">🎨</a> <a href="https://github.com/OpenMined/syft.js/commits?author=cereallarceny" title="Documentation">📖</a> <a href="#business-cereallarceny" title="Business development">💼</a></td> <td align="center"><a href="https://www.linkedin.com/in/vova-manannikov"><img src="https://avatars2.githubusercontent.com/u/12518480?v=4" width="100px;" alt=""/><br /><sub><b>Vova Manannikov</b></sub></a><br /><a href="https://github.com/OpenMined/syft.js/commits?author=vvmnnnkv" title="Code">💻</a> <a href="https://github.com/OpenMined/syft.js/commits?author=vvmnnnkv" title="Documentation">📖</a> <a href="https://github.com/OpenMined/syft.js/commits?author=vvmnnnkv" title="Tests">⚠️</a></td> <td align="center"><a href="http://nolski.rocks"><img src="https://avatars3.githubusercontent.com/u/2600677?v=4" width="100px;" alt=""/><br /><sub><b>Mike Nolan</b></sub></a><br /><a href="https://github.com/OpenMined/syft.js/commits?author=Nolski" title="Code">💻</a></td> <td align="center"><a href="http://ravikantsingh.com"><img src="https://avatars3.githubusercontent.com/u/40258150?v=4" width="100px;" alt=""/><br /><sub><b>Ravikant Singh</b></sub></a><br /><a href="https://github.com/OpenMined/syft.js/commits?author=IamRavikantSingh" title="Code">💻</a> <a href="https://github.com/OpenMined/syft.js/commits?author=IamRavikantSingh" title="Tests">⚠️</a> <a href="https://github.com/OpenMined/syft.js/commits?author=IamRavikantSingh" title="Documentation">📖</a></td> <td align="center"><a href="http://vkkhare.github.io"><img src="https://avatars1.githubusercontent.com/u/18126069?v=4" width="100px;" alt=""/><br /><sub><b>varun khare</b></sub></a><br /><a href="https://github.com/OpenMined/syft.js/commits?author=vkkhare" title="Code">💻</a></td> <td align="center"><a href="https://github.com/pedroespindula"><img src="https://avatars1.githubusercontent.com/u/38431219?v=4" width="100px;" alt=""/><br /><sub><b>Pedro Espíndula</b></sub></a><br /><a href="https://github.com/OpenMined/syft.js/commits?author=pedroespindula" title="Documentation">📖</a></td> <td align="center"><a href="https://benardi.github.io/myblog/"><img src="https://avatars0.githubusercontent.com/u/9937551?v=4" width="100px;" alt=""/><br /><sub><b>José Benardi de Souza Nunes</b></sub></a><br /><a href="https://github.com/OpenMined/syft.js/commits?author=Benardi" title="Tests">⚠️</a></td> </tr> <tr> <td align="center"><a href="http://www.linkedin.com/in/singh-taj"><img src="https://avatars1.githubusercontent.com/u/25232829?v=4" width="100px;" alt=""/><br /><sub><b>Tajinder Singh</b></sub></a><br /><a href="https://github.com/OpenMined/syft.js/commits?author=tsingh2k15" title="Code">💻</a></td> </tr> </table> <!-- markdownlint-enable --> <!-- prettier-ignore-end --> <!-- ALL-CONTRIBUTORS-LIST:END -->

License

Apache License 2.0