Skip to content
This repository has been archived by the owner on Feb 16, 2023. It is now read-only.

Commit

Permalink
Merge pull request #833 from OpenMined/dev
Browse files Browse the repository at this point in the history
Master
  • Loading branch information
cereallarceny authored Apr 1, 2021
2 parents dbcd06f + 2ceaf7e commit 80878e3
Show file tree
Hide file tree
Showing 511 changed files with 45,470 additions and 8,897 deletions.
15 changes: 8 additions & 7 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches:
- master
- dev
- pygrid_0.4.0
pull_request:
types: [opened, synchronize, reopened]

Expand All @@ -14,7 +15,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: [3.7]
python-version: [3.8]

steps:
- uses: actions/checkout@v1
Expand All @@ -26,17 +27,17 @@ jobs:
- name: Install Poetry
run: |
pip install --upgrade pip
pip install poetry==1.0
pip install poetry==1.1.2
- name: Test Grid Node
- name: Test Grid Domain
run: |
cd ./apps/node/
cd ./apps/domain/
# Install dependencies
poetry install
# Run black
poetry run black --check --verbose --exclude src/syft .
poetry run black --check --verbose .
# Run docformatter
poetry run docformatter --check --recursive .
Expand Down Expand Up @@ -78,7 +79,7 @@ jobs:
- name: Run Integration Tests
run: |
cd ./apps/node/
cd ./apps/domain/
# Run Integration tests
poetry run coverage run -m pytest -v ../../tests
# poetry run coverage run -m pytest -v ../../tests
36 changes: 36 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,39 @@ test_flask_grid_server.db
# Sphinx documentation
docs/_build/

# Terraform .gitignore (https://github.com/github/gitignore/blob/master/Terraform.gitignore)

# Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log

# Exclude all .tfvars files, which are likely to contain sentitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
#
*.tfvars

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Include override files you do wish to add to version control using negated pattern
#
# !example_override.tf

# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*

# Ignore CLI configuration files
.terraformrc
terraform.rc
14 changes: 14 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,17 @@ repos:
rev: v1.1.0
hooks:
- id: python-use-type-annotations

- repo: https://github.com/aflc/pre-commit-jupyter
rev: v1.0.0
hooks:
- id: jupyter-notebook-cleanup
args:
- --remove-kernel-metadata
- --pin-patterns
- "[pin];[donotremove]"

- repo: https://github.com/pre-commit/mirrors-isort
rev: 'v5.4.2' # Use the revision sha / tag you want to point at
hooks:
- id: isort
5 changes: 3 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"python.pythonPath": "/Users/cereallarceny/.pyenv/versions/3.7.5/bin/python"
}
"python.formatting.provider": "black",
"editor.tabSize": 4
}
76 changes: 46 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
![PyGrid logo](https://raw.githubusercontent.com/OpenMined/design-assets/master/logos/PyGrid/horizontal-primary-trans.png)

[![Run Tests](https://github.com/OpenMined/PyGrid/workflows/Run%20tests/badge.svg)](https://github.com/OpenMined/PyGrid/actions?query=workflow%3A%22Run+tests%22) [![Docker build](https://github.com/OpenMined/PyGrid/workflows/Docker%20build/badge.svg)](https://github.com/OpenMined/PyGrid/actions?query=workflow%3A%22Docker+build%22)
[![Tests](https://github.com/OpenMined/PyGrid/workflows/Run%20tests/badge.svg)](https://github.com/OpenMined/PyGrid/actions?query=workflow%3A%22Run+tests%22)

PyGrid is a peer-to-peer network of data owners and data scientists who can collectively train AI models using [PySyft](https://github.com/OpenMined/PySyft/). PyGrid is also the central server for conducting both model-centric and data-centric federated learning.

_**A quick note about PySyft 0.3.x:** Currently, PyGrid is designed to work with the PySyft 0.2.x product line only. We are working on support for 0.3.x and hope to have this released by early 2021. Thanks for your patience!_
You may control PyGrid via our user-interface, [PyGrid Admin](https://github.com/OpenMined/pygrid-admin).

## Architecture

PyGrid platform is composed by three different components.

- **Network** - A Flask-based application used to manage, monitor, control, and route instructions to various PyGrid Nodes.
- **Node** - A Flask-based application used to store private data and models for federated learning, as well as to issue instructions to various PyGrid Workers.
- **Worker** - An emphemeral instance, managed by a PyGrid Node, that is used to compute data.
- **Network** - A Flask-based application used to manage, monitor, control, and route instructions to various PyGrid Domains.
- **Domain** - A Flask-based application used to store private data and models for federated learning, as well as to issue instructions to various PyGrid Workers.
- **Worker** - An emphemeral instance, managed by a PyGrid Domain, that is used to compute data.

## Use Cases

Expand All @@ -30,41 +30,41 @@ Model-centric FL is when the model is hosted in PyGrid. This is really useful wh
4. Once training is completed, a "diff" is generated between the new and the original state of the model
5. The diff is reported back to PyGrid and it's averaged into the model

This takes place potentially with hundreds, or thousands of devices simultaneously. **For model-centric federated learning, you only need to run a Node. Networks and Workers are irrelevant for this specific use-case.**
This takes place potentially with hundreds, or thousands of devices simultaneously. **For model-centric federated learning, you only need to run a Domain. Networks and Workers are irrelevant for this specific use-case.**

_Note:_ For posterity sake, we previously used to refer to this process as "static federated learning".

![Cycled MCFL](https://github.com/OpenMined/PyGrid/blob/dev/assets/MCFL-cycled.png?raw=true)
![Cycled MCFL](assets/MCFL-cycled.png)

#### Data-centric FL

Data-centric FL is the same problem as model-centric FL, but from the opposite perspective. The most likely scenario for data-centric FL is where a person or organization has data they want to protect in PyGrid (instead of hosting the model, they host data). This would allow a data scientist who is not the data owner, to make requests for training or inference against that data. The following workflow will take place:

1. A data scientist searches for data they would like to train on (they can search either an individual Node, or a Network of Nodes)
1. A data scientist searches for data they would like to train on (they can search either an individual Domain, or a Network of Domains)
2. Once the data has been found, they may write a training plan and optionally pre-train a model
3. The training plan and model are sent to the PyGrid Node in the form of a job request
4. The PyGrid Node will gather the appropriate data from its database and send the data, the model, and the training plan to a Worker for processing
3. The training plan and model are sent to the PyGrid Domain in the form of a job request
4. The PyGrid Domain will gather the appropriate data from its database and send the data, the model, and the training plan to a Worker for processing
5. The Worker performs the plan on the model using the data
6. The result is returned to the Node
6. The result is returned to the Domain
7. The result is returned to the data scientist

For the last step, we're working on adding the capability for privacy budget tracking to be applied that will allow a data owner to "sign off" on whether or not a trained model should be released.

_Note:_ For posterity sake, we previously used to refer to this process as "dynamic federated learning".

**Node-only data-centric FL**
**Domain-only data-centric FL**

Technically speaking, it isn't required to run a Network when performing data-centric federated learning. Alternatively, as a data owner, you may opt to only run a Node, but participate in a Network hosted by someone else. The Network host will not have access to your data.
Technically speaking, it isn't required to run a Network when performing data-centric federated learning. Alternatively, as a data owner, you may opt to only run a Domain, but participate in a Network hosted by someone else. The Network host will not have access to your data.

![Node-only DCFL](https://github.com/OpenMined/PyGrid/blob/dev/assets/DCFL-node.png?raw=true)
![Domain-only DCFL](assets/DCFL-node.png)

**Network-based data-centric FL**

Many times you will wat to use a Network to allow multiple Nodes to be connected together. As a data owner, it's not strictly necessary to own and operate mulitple Nodes. PyGrid doesn't prescribe one way to organize Nodes and Networks, but we expose these applications to allow you and various related stakeholders to make the correct decision about your infrastructure needs.
Many times you will wat to use a Network to allow multiple Domains to be connected together. As a data owner, it's not strictly necessary to own and operate mulitple Domains. PyGrid doesn't prescribe one way to organize Domains and Networks, but we expose these applications to allow you and various related stakeholders to make the correct decision about your infrastructure needs.

![Network-based DCFL](https://github.com/OpenMined/PyGrid/blob/dev/assets/DCFL-network.png?raw=true)
![Network-based DCFL](assets/DCFL-network.png)

## Getting started
## Local Setup

Currently, we suggest two ways to run PyGrid locally: Docker and manually running from source. With Docker, we can organize all the services we'd like to use and then boot them all in one command. With manually running from source, we have to run them as separate tasks.

Expand All @@ -74,14 +74,14 @@ To install Docker, just follow the [docker documentation](https://docs.docker.co

#### 1. Setting the your hostfile

Before start the grid platform locally using Docker, we need to set up the domain names used by the bridge network. In order to use these nodes from outside of the containers context, you should add the following domain names on your `/etc/hosts`
Before start the grid platform locally using Docker, we need to set up the domain names used by the bridge network. In order to use these Domains from outside of the containers context, you should add the following domain names on your `/etc/hosts`

```
127.0.0.1 network
127.0.0.1 bob
127.0.0.1 alice
127.0.0.1 bill
127.0.0.1 james
127.0.0.1 bob
127.0.0.1 charlie
127.0.0.1 dan
```

Note that you're not restricted to running 4 nodes and a network. You could instead run just a single node if you'd like - this is often all you need for model-centric federated learning. For the sake of our example, we'll use the network running 4 nodes underneath but you're welcome to modify it to your needs.
Expand All @@ -90,8 +90,9 @@ Note that you're not restricted to running 4 nodes and a network. You could inst

The latest PyGrid Network and Node images are also available on the Docker Hub.

- [PyGrid Domain - `openmined/grid-domain`](https://hub.docker.com/repository/docker/openmined/grid-domain)
- [PyGrid Worker - `openmined/grid-worker`](https://hub.docker.com/repository/docker/openmined/grid-worker)
- [PyGrid Network - `openmined/grid-network`](https://hub.docker.com/repository/docker/openmined/grid-network)
- [PyGrid Node - `openmined/grid-node`](https://hub.docker.com/repository/docker/openmined/grid-node)

To setup and start the PyGrid platform you just need start the docker-compose process.

Expand All @@ -106,19 +107,29 @@ This will download the latest Openmined Docker images and start a grid platform
If you want to build your own custom images, you may do so using the following command for the Node:

```
docker build . --file ./apps/node/Dockerfile --tag openmined/grid-node:mybuildname
docker build ./apps/domain --file ./apps/domain/Dockerfile --tag openmined/grid-domain:mybuildname
```

Or for the Worker:

```
docker build ./apps/worker --file ./apps/worker/Dockerfile --tag openmined/grid-worker:mybuildname
```

Or for the Network:

```
docker build . --file ./apps/node/Dockerfile --tag openmined/grid-node:mybuildname
docker build ./apps/network --file ./apps/network/Dockerfile --tag openmined/grid-network:mybuildname
```

### Manual Start

#### Running a Node

> ##### Installation
>
> First install [`poetry`](https://python-poetry.org/docs/) and run `poetry install` in `apps/node`
To start the PyGrid Node manually, run:

```
Expand All @@ -132,15 +143,15 @@ You can pass the arguments or use environment variables to set the network confi

- `-h, --help` - Shows the help message and exit
- `-p [PORT], --port [PORT]` - Port to run server on (default: 5000)
- `--host [HOST]` - The Network host
- `--host [HOST]` - The Node host
- `--num_replicas [NUM]` - The number of replicas to provide fault tolerance to model hosting
- `--id [ID]` - The ID of the Node
- `--start_local_db` - If this flag is used a SQLAlchemy DB URI is generated to use a local db

**Environment Variables**

- `GRID_NETWORK_PORT` - Port to run server on
- `GRID_NETWORK_HOST` - The Network host
- `GRID_NODE_PORT` - Port to run server on
- `GRID_NODE_HOST` - The Node host
- `NUM_REPLICAS` - Number of replicas to provide fault tolerance to model hosting
- `DATABASE_URL` - The Node database URL
- `SECRET_KEY` - The secret key
Expand All @@ -151,15 +162,15 @@ To start the PyGrid Network manually, run:

```
cd apps/network
./run.sh --port 5000 --start_local_db
./run.sh --port 7000 --start_local_db
```

You can pass the arguments or use environment variables to set the network configs.

**Arguments**

- `-h, --help` - Shows the help message and exit
- `-p [PORT], --port [PORT]` - Port to run server on (default: 5000)
- `-p [PORT], --port [PORT]` - Port to run server on (default: 7000)
- `--host [HOST]` - The Network host
- `--start_local_db` - If this flag is used a SQLAlchemy DB URI is generated to use a local db

Expand All @@ -170,13 +181,18 @@ You can pass the arguments or use environment variables to set the network confi
- `DATABASE_URL` - The Network database URL
- `SECRET_KEY` - The secret key

## Deployment & CLI

[Please check the instruction for deployment and CLI here.](deployment.md)


## Contributing

If you're interested in contributing, check out our [Contributor Guidelines](CONTRIBUTING.md).

## Support

For support in using this library, please join the **#lib_pygrid** Slack channel. If you’d like to follow along with any code changes to the library, please join the **#code_pygrid** Slack channel. [Click here to join our Slack community!](https://slack.openmined.org)
For support in using this library, please join the **#support** Slack channel. [Click here to join our Slack community!](https://slack.openmined.org)

## License

Expand Down
File renamed without changes.
17 changes: 17 additions & 0 deletions apps/domain/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM python:3.8

RUN mkdir /app
WORKDIR /app

RUN apt-get update
RUN apt-get install -y git python-dev python3-dev

RUN pip install poetry
COPY poetry.lock pyproject.toml entrypoint.sh /app/
COPY /src /app/src

WORKDIR /app/
RUN poetry export -f requirements.txt --output requirements.txt --without-hashes
RUN pip3 install -r requirements.txt

ENTRYPOINT ["sh", "entrypoint.sh"]
File renamed without changes.
3 changes: 3 additions & 0 deletions apps/domain/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
exec poetry run gunicorn --chdir ./src -k flask_sockets.worker --bind 0.0.0.0:$PORT wsgi:app \
"$@"
Loading

0 comments on commit 80878e3

Please sign in to comment.