Skip to content

Commit

Permalink
Merge pull request #52 from Xilinx/dev
Browse files Browse the repository at this point in the history
Release v0.0.6
  • Loading branch information
mmrahorovic authored Feb 10, 2023
2 parents 7123fa5 + 6ef1980 commit 3cdec2b
Show file tree
Hide file tree
Showing 30 changed files with 1,848 additions and 931 deletions.
101 changes: 82 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
## <img src=https://raw.githubusercontent.com/Xilinx/finn/github-pages/docs/img/finn-logo.png width=128/> Dataflow Accelerator Examples
*for PYNQ on Zynq and Alveo*
# <img src=https://raw.githubusercontent.com/Xilinx/finn/github-pages/docs/img/finn-logo.png width=200 style="margin-bottom: -15px; margin-right: 10px"/> Dataflow Accelerator Examples
<p align="center"> <em>for PYNQ on Zynq and Alveo</em> <p>
<p align="left">
<a>
<img src="https://img.shields.io/github/v/release/Xilinx/finn-examples?color=%09%23228B22&display_name=tag&label=Release" />
</a>
<a href="https://github.com/Xilinx/finn/tree/v0.9">
<img src="https://img.shields.io/badge/FINN-v0.9.0-blue" />
</a>
<a href="https://github.com/Xilinx/PYNQ/tree/v3.0.1">
<img src="https://img.shields.io/badge/PYNQ-v3.0.1-blue" />
</a>
<a href="https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/2022-1.html">
<img src="https://img.shields.io/badge/Vivado%2FVitis-v2022.1-blue" />
</a>
</p>

<img align="left" src="docs/img/finn-example.png" alt="drawing" style="margin-right: 20px" width="250"/>

Expand All @@ -18,34 +32,81 @@ Need help with a problem in this repo, or got a question? Feel free to ask for h
In the past, we also had a [Gitter channel](https://gitter.im/xilinx-finn/community). Please be aware that this is no longer maintained by us but can still be used to search for questions previous users had.

## Quickstart
*We recommend PYNQ version 3.0.1, but older installations of PYNQ should also work. For PYNQ v2.6.1, please refer for set-up instructions to [FINN-examples v0.0.5](https://github.com/Xilinx/finn-examples/tree/v0.0.5).*

### Zynq
*For ZYNQ boards, all commands below must be prefixed with `sudo` or by first going into `sudo su`.*

*For Alveo we recommend setting up everything inside a virtualenv as described [here](https://pynq.readthedocs.io/en/v2.6.1/getting_started/alveo_getting_started.html?highlight=alveo#install-conda).*
*For PYNQ boards, all commands below must be prefixed with `sudo` or by first going into `sudo su`. We recommend PYNQ version 2.6.1 as some installation issues have been reported for PYNQ version 2.7.*
First, source the PYNQ and XRT virtual environment:

```shell
source /etc/profile.d/pynq_venv.sh
source /etc/profile.d/xrt_setup.sh
```

First, ensure that your `pip` and `setuptools` installations are up-to-date
on your PYNQ board or Alveo server:
Next, ensure that your `pip` and `setuptools` installations are up-to-date
on your PYNQ board:

```shell
python3 -m pip install --upgrade pip setuptools
python3 -m pip install pip==23.0 setuptools==67.1.0
```

Since we are going to install finn-examples without build-isolation, we need to ensure all dependencies are installed. For that, install `setuptools_csm` as well:

```shell
python3 -m pip install setuptools_scm==7.1.0
```

Install the `finn-examples` package using `pip`:

```shell
# remove previous versions with: pip3 uninstall finn-examples
pip3 install finn-examples
pip3 install finn-examples --no-build-isolation
# to install particular git branch:
# pip3 install git+https://github.com/Xilinx/finn-examples.git@dev
# pip3 install git+https://github.com/Xilinx/finn-examples.git@dev --no-build-isolation
```

Retrieve the example Jupyter notebooks using the PYNQ get-notebooks command:
Retrieve the example Jupyter notebooks using the PYNQ get-notebooks command. An example of how to run the Jupyter notebook server, assuming we are forwarding port 8888 from the target to some port on our local machine, is also shown below:

```shell
# on PYNQ boards, first cd /home/xilinx/jupyter_notebooks
pynq get-notebooks --from-package finn-examples -p . --force
jupyter-notebook --no-browser --allow-root --port=8888
```

### Alveo
*For Alveo we recommend setting up everything inside a virtualenv as described [here](https://pynq.readthedocs.io/en/v2.6.1/getting_started/alveo_getting_started.html?highlight=alveo#install-conda).*

First, create & source a virtual environment:
```shell
conda create -n <virtual-env> python=3.10
conda activate <virtual-env>
```

Next, ensure that your `pip` and `setuptools` installations are up-to-date:
```shell
python3 -m pip install --upgrade pip==23.0 setuptools==67.2.0
```

Finally, we can now install Pynq, FINN-examples and Jupyter (please note to source the XRT environment before):
```shell
pip3 install pynq==3.0.1
python3 -m pip install setuptools_scm==7.1.0 ipython==8.9.0
pip3 install finn-examples --no-build-isolation
# to install particular git branch:
# pip3 install git+https://github.com/Xilinx/finn-examples.git@dev --no-build-isolation
python3 -m pip install jupyter==1.0.0
```

Retrieve the example Jupyter notebooks using the PYNQ get-notebooks command. An example of how to run the Jupyter notebook server is also shown below:

```shell
pynq get-notebooks --from-package finn-examples -p . --force
jupyter-notebook --no-browser --port=8888
```

***

You can now navigate the provided Jupyter notebook examples, or just use the
provided accelerators as part of your own Python program:

Expand All @@ -56,23 +117,25 @@ import numpy as np
# instantiate the accelerator
accel = models.cnv_w2a2_cifar10()
# generate an empty numpy array to use as input
dummy_in = np.empty(accel.ishape_normal, dtype=np.uint8)
dummy_in = np.empty(accel.ishape_normal(), dtype=np.uint8)
# perform inference and get output
dummy_out = accel.execute(dummy_in)
```

## Example Neural Network Accelerators
| Dataset | Topology | Quantization | Supported boards | Supported build flows
|----------------------------------------------------------------|-------------------------|------------------------------------------------------------|------------------|------------------|
| <img src="docs/img/cifar-10.png" width="150"/><br/>CIFAR-10 | CNV (VGG-11-like) | several variants:<br>1/2-bit weights/activations | all | Pynq-Z1<br>ZCU104<br>Ultra96 |
| <img src="docs/img/mnist.jpg" width="150"/><br/><br>MNIST | 3-layer fully-connected | several variants:<br>1/2-bit weights/activations | all | Pynq-Z1<br>ZCU104<br>Ultra96 |
| <img src="docs/img/imagenet.jpg" width="150"/><br/><br>ImageNet | MobileNet-v1 | 4-bit weights and activations<br>8-bit first layer weights | Alveo U250<br>ZCU104 | ZCU104 |
| <img src="docs/img/cifar-10.png" width="150"/><br/>CIFAR-10 | CNV (VGG-11-like) | several variants:<br>1/2-bit weights/activations | Pynq-Z1<br>ZCU104<br>Ultra96<br>U250 | Pynq-Z1<br>ZCU104<br>Ultra96<br>U250 |
| <img src="docs/img/mnist.jpg" width="150"/><br/><br>MNIST | 3-layer fully-connected | several variants:<br>1/2-bit weights/activations | Pynq-Z1<br>ZCU104<br>Ultra96<br>U250 | Pynq-Z1<br>ZCU104<br>Ultra96<br>U250 |
| <img src="docs/img/imagenet.jpg" width="150"/><br/><br>ImageNet | MobileNet-v1 | 4-bit weights & activations<br>8-bit first layer weights | Alveo U250 | Alveo U250 |
| <img src="docs/img/imagenet.jpg" width="150"/><br/><br>ImageNet | ResNet-50 | 1-bit weights 2-bit activations<br>4-bit residuals<br>8-bit first/last layer weights | Alveo U250 | - |
| <img src="docs/img/radioml.png" width="150"/><br/><br>RadioML 2018 | 1D CNN (VGG10) | 4-bit weights and activations | ZCU104 | ZCU104 |
| <img src="docs/img/maskedfacenet.jpg" width="150"/><br/><br>MaskedFace-Net | [BinaryCoP](https://arxiv.org/pdf/2102.03456)<br/>*Contributed by TU Munich+BMW* | 1-bit weights and activations | Pynq-Z1 | Pynq-Z1 |
| <img src="docs/img/keyword-spotting.png" width="150"/><br/><br>Google Speech Commands v2 | 3-layer fully-connected | 3-bit weights and activations | Pynq-Z1 | Pynq-Z1 |
| <img src="docs/img/radioml.png" width="150"/><br/><br>RadioML 2018 | 1D CNN (VGG10) | 4-bit weights & activations | ZCU104 | ZCU104 |
| <img src="docs/img/maskedfacenet.jpg" width="150"/><br/><br>MaskedFace-Net | [BinaryCoP](https://arxiv.org/pdf/2102.03456)<br/>*Contributed by TU Munich+BMW* | 1-bit weights & activations | Pynq-Z1 | Pynq-Z1 |
| <img src="docs/img/keyword-spotting.png" width="150"/><br/><br>Google Speech Commands v2 | 3-layer fully-connected | 3-bit weights & activations | Pynq-Z1 | Pynq-Z1 |
| <img src="docs/img/unsw-nb15.jpg" width="150"/><br/><br>UNSW-NB15 | 4-layer fully-connected | 2-bit weights & activations | Pynq-Z1 <br> ZCU104 <br> Ultra96 | Pynq-Z1 <br> ZCU104 <br> Ultra96 |

*Please note that for the non-supported Alveo build flows, you can use the pre-built FPGA bitfiles generated with older versions of the Vitis/Vivado tools. These bitfiles target the following Alveo U250 platform: [xilinx_u250_xdma_201830_2](https://www.xilinx.com/products/boards-and-kits/alveo/package-files-archive/u250-2018-3-1.html).
*Please note that the build flow for ResNet-50 for the Alveo U250 has known issues and we're currently working on resolving them. However, you can still execute the associated notebook, as we provide a pre-built FPGA bitfile generated with an older Vivado (/FINN) version targeting the [xilinx_u250_xdma_201830_2](https://www.xilinx.com/products/boards-and-kits/alveo/package-files-archive/u250-2018-3-1.html) platform.* <br>
*Furthermore, please note that you can target other boards (such as the Pynq-Z2 or ZCU102) by changing the build script manually, but these accelerators have not been tested.*

We welcome community contributions to add more examples to this repo!

Expand All @@ -82,7 +145,7 @@ We welcome community contributions to add more examples to this repo!

`finn-examples` provides pre-built FPGA bitfiles for the following boards:

* **Edge:** Pynq-Z1, Pynq-Z2, Ultra96 and ZCU104
* **Edge:** Pynq-Z1, Ultra96 and ZCU104
* **Datacenter:** Alveo U250

It's possible to generate Vivado IP for the provided examples to target *any*
Expand Down
4 changes: 2 additions & 2 deletions build/bnn-pynq/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ FINN_EXAMPLES=/path/to/finn-examples
# cd into finn submodule
cd $FINN_EXAMPLES/build/finn
# launch the build on the bnn-pynq folder
./run-docker.sh build_custom /path/to/finn-examples/build/bnn-pynq
./run-docker.sh build_custom $FINN_EXAMPLES/build/bnn-pynq
```

5. The generated outputs will be under `bnn-pynq/output_<topology>_<platform>`. You can find a description of the generated files [here](https://finn-dev.readthedocs.io/en/latest/command_line.html#simple-dataflow-build-mode).

## Where did those ONNX model files come from?

The BNN-PYNQ networks are part of the
[Brevitas examples](https://github.com/Xilinx/brevitas/tree/master/brevitas_examples/bnn_pynq). You can find the details on quantization, accuracy, layers used in the Brevitas repo, as well as the training scripts if you'd like to retrain them yourself.
[Brevitas examples](https://github.com/Xilinx/brevitas/tree/master/src/brevitas_examples/bnn_pynq). You can find the details on quantization, accuracy, layers used in the Brevitas repo, as well as the training scripts if you'd like to retrain them yourself.

Subsequently, those trained networks are [exported to ONNX](https://github.com/Xilinx/finn/blob/master/notebooks/basics/1_brevitas_network_import.ipynb). In addition, the particular versions
used here have two additions, as described in the "Adding Pre- and Postprocessing" section of [this notebook](https://github.com/Xilinx/finn/blob/master/notebooks/end2end_example/bnn-pynq/tfc_end2end_example.ipynb):
Expand Down
2 changes: 1 addition & 1 deletion build/build-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ SCRIPT=$(readlink -f "$0")
# absolute path this script is in, thus /home/user/bin
SCRIPTPATH=$(dirname "$SCRIPT")
# subdirs for all finn-examples build folders
BUILD_FOLDERS="bnn-pynq kws mobilenet-v1 resnet50 vgg10-radioml"
BUILD_FOLDERS="bnn-pynq kws mobilenet-v1 resnet50 vgg10-radioml cybersecurity-mlp"
# all HW platforms we build for
PLATFORMS="Pynq-Z1 Ultra96 ZCU104 U250"

Expand Down
22 changes: 22 additions & 0 deletions build/cybersecurity-mlp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# The multilayer perceptron for cybersecurity use-cases
The multi layer perceptron (MLP) for the cybersecurity use-case is based on the three-part tutorial for training a quantized MLP and deploying it with FINN, which is provided in the FINN [end-to-end example repository](https://github.com/Xilinx/finn/tree/main/notebooks/end2end_example). The MLP consists of four fully-connected layers in total: three hidden layers with 64 neurons, and a final output layer with a single output, all using 2-bit weights. For more information on training the network, or more details behind what's happening under the hood, the notebooks provided in the FINN end-to-end example repository serve as an excellent starting point.

# Build bitfiles for MLP example
0. Ensure you have performed the *Setup* steps in the top-level README for setting up the FINN requirements and environment variables.

1. Edit the `mlp-cybersecurity/build.py` to restrict the platform variables to the ones that you are interested in, e.g. `platforms_to_build = ["Pynq-Z1"]`. You can also change the other build configuration options, see the [FINN docs](https://finn-dev.readthedocs.io/en/latest/source_code/finn.util.html#finn.util.build_dataflow.DataflowBuildConfig) for a full explanation.

2. Launch the build as follows:
```shell
# update this according to where you cloned this repo:
FINN_EXAMPLES=/path/to/finn-examples
# cd into finn submodule
cd $FINN_EXAMPLES/build/finn
# launch the build on the cybersecurity-mlp folder
./run-docker.sh build_custom $FINN_EXAMPLES/build/cybersecurity-mlp
```

3. The generated outputs will be under `cybersecurity-mlp/output_<topology>_<platform>`. You can find a description of the generated files [here](https://finn-dev.readthedocs.io/en/latest/command_line.html#simple-dataflow-build-mode).

# Where did the ONNX model file come from?
The ONNX model is created and exported prior to the build flow is launched. You can find the details of this process in the `cybersecurity-mlp/custom_steps.py` file.
78 changes: 78 additions & 0 deletions build/cybersecurity-mlp/build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import finn.builder.build_dataflow as build
import finn.builder.build_dataflow_config as build_cfg
from finn.util.basic import alveo_default_platform
import os
import shutil
from custom_steps import custom_step_mlp_export

# Which platforms to build the networks for
zynq_platforms = ["Pynq-Z1", "Ultra96", "ZCU104"]
alveo_platforms = []

# Note: only zynq platforms currently tested
platforms_to_build = zynq_platforms + alveo_platforms

# determine which shell flow to use for a given platform
def platform_to_shell(platform):
if platform in zynq_platforms:
return build_cfg.ShellFlowType.VIVADO_ZYNQ
elif platform in alveo_platforms:
return build_cfg.ShellFlowType.VITIS_ALVEO
else:
raise Exception("Unknown platform, can't determine ShellFlowType")

# Define model name
model_name = "unsw_nb15-mlp-w2a2"

# Create a release dir, used for finn-examples release packaging
os.makedirs("release", exist_ok=True)

for platform_name in platforms_to_build:
shell_flow_type = platform_to_shell(platform_name)
if shell_flow_type == build_cfg.ShellFlowType.VITIS_ALVEO:
vitis_platform = alveo_default_platform[platform_name]
# for Alveo, use the Vitis platform name as the release name
# e.g. xilinx_u250_xdma_201830_2
release_platform_name = vitis_platform
else:
vitis_platform = None
# for Zynq, use the board name as the release name
# e.g. ZCU104
release_platform_name = platform_name
platform_dir = "release/%s" % release_platform_name
os.makedirs(platform_dir, exist_ok=True)
# Set up the build configuration for this model
cfg = build_cfg.DataflowBuildConfig(
output_dir = "output_%s_%s" % (model_name, release_platform_name),
mvau_wwidth_max = 80,
target_fps = 1000000,
synth_clk_period_ns = 10.0,
board = platform_name,
shell_flow_type = shell_flow_type,
vitis_platform = vitis_platform,
vitis_opt_strategy = build_cfg.VitisOptStrategyCfg.PERFORMANCE_BEST,
generate_outputs = [
build_cfg.DataflowOutputType.PYNQ_DRIVER,
build_cfg.DataflowOutputType.ESTIMATE_REPORTS,
build_cfg.DataflowOutputType.BITFILE,
build_cfg.DataflowOutputType.DEPLOYMENT_PACKAGE,
],
save_intermediate_models=True
)

# Export MLP model to FINN-ONNX
model = custom_step_mlp_export(model_name)
# Launch FINN compiler to generate bitfile
build.build_dataflow_cfg(model, cfg)
# Copy bitfiles into release dir if found
bitfile_gen_dir = cfg.output_dir + "/bitfile"
filtes_to_check_and_copy = [
"finn-accel.bit",
"finn-accel.hwh",
"finn-accel.xclbin"
]
for f in filtes_to_check_and_copy:
src_file = bitfile_gen_dir + "/" + f
dst_file = platform_dir + "/" + f.replace("finn-accel", model_name)
if os.path.isfile(src_file):
shutil.copy(src_file, dst_file)
Loading

0 comments on commit 3cdec2b

Please sign in to comment.