From 128b360228e547d06e6f7b3c604a78d6643ce177 Mon Sep 17 00:00:00 2001 From: durgabhavaniv <42232855+durgabhavaniv@users.noreply.github.com> Date: Mon, 3 Jun 2019 17:14:52 +0530 Subject: [PATCH 1/7] Update README.md --- examples/caffe/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/caffe/README.md b/examples/caffe/README.md index dac35d6ff..835eb79a4 100644 --- a/examples/caffe/README.md +++ b/examples/caffe/README.md @@ -69,7 +69,7 @@ After the setup, run through a sample end to end caffe classification example us 4. **Inference** - Run a single image on the FPGA ``` - python run.py --prototxt /opt/models/caffe/bvlc_googlenet/bvlc_googlenet_train_val.prototxt --caffemodel /opt/models/caffe/bvlc_googlenet/bvlc_googlenet.caffemodel --image ../deployment_modes/dog.jpg + python run.py --image ../deployment_modes/dog.jpg ``` 5. **Benchmark FPGA performance** - evaluate network throughput and/or latency in a streaming deployment scenario (FPGA only) From bcb744b90697de73083389b59fbe9997ad49d3a3 Mon Sep 17 00:00:00 2001 From: durgabhavaniv <42232855+durgabhavaniv@users.noreply.github.com> Date: Fri, 7 Jun 2019 20:18:08 +0530 Subject: [PATCH 2/7] Add files via upload --- docs/img/image_classifier_caffe.png | Bin 0 -> 34472 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/img/image_classifier_caffe.png diff --git a/docs/img/image_classifier_caffe.png b/docs/img/image_classifier_caffe.png new file mode 100644 index 0000000000000000000000000000000000000000..14148826af1f8824f695fb8afa4f80d5ecad9792 GIT binary patch literal 34472 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 h-v|Ha Date: Sun, 9 Jun 2019 23:30:12 +0530 Subject: [PATCH 3/7] Add files via upload --- examples/caffe/caffe_run.py | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 examples/caffe/caffe_run.py diff --git a/examples/caffe/caffe_run.py b/examples/caffe/caffe_run.py new file mode 100644 index 000000000..bc153acc1 --- /dev/null +++ b/examples/caffe/caffe_run.py @@ -0,0 +1,39 @@ +from __future__ import print_function + +import os,sys,argparse +import caffe +import io +import numpy as np +import xdnn_io + +# Use this routine to classify a single image +def Classify(prototxt,caffemodel,image,labels): + classifier = caffe.Classifier(prototxt,caffemodel, + image_dims=[256,256], mean=np.array([104,117,123]), + raw_scale=255, channel_swap=[2,1,0]) + predictions = classifier.predict([caffe.io.load_image(image)]).flatten() + labels = np.loadtxt(labels, str, delimiter='\t') + top_k = predictions.argsort()[-1:-6:-1] + for l,p in zip(labels[top_k],predictions[top_k]): + print (l," : ",p) + return classifier + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='pyXFDNN') + parser.add_argument('--caffemodel', default="/opt/ml-suite/share/quantize_results/deploy.caffemodel", help='path to caffe model eg: /opt/ml-suite/share/quantize_results/deploy.caffemodel') + parser.add_argument('--prototxt', default="/opt/ml-suite/share/xfdnn_auto_cut_deploy.prototxt", help='path to prototxt file eg: /opt/ml-suite/share/xfdnn_auto_cut_deploy.prototxt') + parser.add_argument('--synset_words', default="/opt/ml-suite/examples/deployment_modes/synset_words.txt", help='path to synset_words eg: /opt/ml-suite/examples/deployment_modes/synset_words.txt') + parser.add_argument('--image', default="/opt/ml-suite/examples/deployment_modes/dog.jpg") + args = vars(parser.parse_args()) + + if args["caffemodel"]: + model=args["caffemodel"] + if args["prototxt"]: + prototxt=args["prototxt"] + if args["synset_words"]: + synset_words=args["synset_words"] + if args["image"]: + image=args["image"] + + print("Loading FPGA with image and classify...") + Classify(prototxt, model, image, synset_words) From 25f85cfea45eb5a5515ca1e9bc5ec02b3dcc5938 Mon Sep 17 00:00:00 2001 From: durgabhavaniv <42232855+durgabhavaniv@users.noreply.github.com> Date: Sun, 9 Jun 2019 23:35:47 +0530 Subject: [PATCH 4/7] Create image_classifier_terminal_caffe.md --- docs/image_classifier_terminal_caffe.md | 86 +++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 docs/image_classifier_terminal_caffe.md diff --git a/docs/image_classifier_terminal_caffe.md b/docs/image_classifier_terminal_caffe.md new file mode 100644 index 000000000..7efe18b24 --- /dev/null +++ b/docs/image_classifier_terminal_caffe.md @@ -0,0 +1,86 @@ +## Running an image classifier with caffe model in docker containers. + +1. Clone ML Suite + + ``` + git clone https://github.com/Xilinx/ml-suite.git + ``` + +2. Download ml-suite container + + ``` + https://www.xilinx.com/member/forms/download/eula-xef.html?filename=xilinx-ml-suite-ubuntu-16.04-xrt-2018.2-caffe-mls-1.4.tar.gz + ``` + +3. Load container + + ``` + sudo docker load < xilinx-ml-suite-ubuntu-16.04-xrt-2018.2-caffe-mls-1.4.tar.gz + ``` + +4. Run docker container + + ``` + $ cd ml-suite + $ sudo ./docker_run.sh + ``` + +5. One time setup + + ``` + python -m ck pull repo:ck-env + python -m ck install package:imagenet-2012-val-min + python -m ck install package:imagenet-2012-aux + head -n 500 $HOME/CK-TOOLS/dataset-imagenet-ilsvrc2012-aux/val.txt > $HOME/CK-TOOLS/dataset-imagenet-ilsvrc2012-val-min/val_map.txt + ``` + + Resize all the images to a common dimension for Caffe + ``` + python -m pip --no-cache-dir install opencv-python --user + python MLsuite/examples/caffe/resize.py $HOME/CK-TOOLS/dataset-imagenet-ilsvrc2012-val-min 256 256 + ``` + + Get necessary models + ``` + cd /opt/ml-suite/examples/caffe + python getModels.py + ``` + +6. environment setup + + ``` + export MLSUITE_ROOT=/opt/ml-suite + source $MLSUITE_ROOT/overlaybins/setup.sh + ``` + +7. **Quantize the model** - The quantizer will generate scaling parameters for quantizing floats INT8. This is required, because FPGAs will take advantage of Fixed Point Precision, to achieve more parallelization at lower power + + ``` + cd /opt/ml-suite/share + export DECENT_DEBUG=1 + /opt/caffe/build/tools/decent_q quantize -model /opt/models/caffe/bvlc_googlenet/bvlc_googlenet_train_val.prototxt -weights /opt/models/caffe/bvlc_googlenet/bvlc_googlenet.caffemodel -auto_test -test_iter 1 --calib_iter 1 + ``` + + This outputs quantize_info.txt, deploy.prototxt, deploy.caffemodel to $HOME/share/quantize_results/ directory + +8. **Compile the Model** - In this step, the network Graph (prototxt) and the Weights (caffemodel) are compiled by the compiler + + ``` + python $MLSUITE_ROOT/xfdnn/tools/compile/bin/xfdnn_compiler_caffe.pyc -b 1 -i 96 -m 9 -d 256 -mix --pipelineconvmaxpool --usedeephi --quant_cfgfile quantize_results/quantize_info.txt -n quantize_results/deploy.prototxt -w quantize_results/deploy.caffemodel -g work/compiler -qz work/quantizer -C + ``` + + This outputs compiler.json, quantizer.json and deploy.caffemodel_data.h5 to $HOME/share/work/ directory + +9. **Subgraph Cutting** - In this step, the original graph is cut, and a custom FPGA accelerated python layer is inserted to be used for Inference. + + ``` + python $MLSUITE_ROOT/xfdnn/rt/scripts/framework/caffe/xfdnn_subgraph.py --inproto quantize_results/deploy.prototxt --trainproto /opt/models/caffe/bvlc_googlenet/bvlc_googlenet_train_val.prototxt --outproto xfdnn_auto_cut_deploy.prototxt --cutAfter data --xclbin $MLSUITE_ROOT/overlaybins/$MLSUITE_PLATFORM/overlay_4.xclbin --netcfg work/compiler.json --quantizecfg work/quantizer.json --weights work/deploy.caffemodel_data.h5 --profile True + ``` + + This output xfdnn_auto_cut_deploy.prototxt to $HOME/share/ directory + +10. Running image classification for caffe model. + + ``` + python $MLSUITE_ROOT/examples/caffe/caffe_run.py --caffemodel $MLSUITE_ROOT/share/quantize_results/deploy.caffemodel --prototxt $MLSUITE_ROOT/share/xfdnn_auto_cut_deploy.prototxt --synset_words $MLSUITE_ROOT/examples/deployment_modes/synset_words.txt --image $MLSUITE_ROOT/examples/deployment_modes/dog.jpg + ``` From 66aece16a42c57cd790c4a4433dc514ddff9882f Mon Sep 17 00:00:00 2001 From: durgabhavaniv <42232855+durgabhavaniv@users.noreply.github.com> Date: Wed, 31 Jul 2019 18:17:01 +0530 Subject: [PATCH 5/7] Update docker_run.sh --- docker_run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker_run.sh b/docker_run.sh index 7cbff37e2..3f572e591 100755 --- a/docker_run.sh +++ b/docker_run.sh @@ -30,5 +30,5 @@ docker run \ $docker_devices \ -v $HERE/share:/opt/ml-suite/share \ -w /opt/ml-suite \ - xilinx-ml-suite-ubuntu-16.04-xrt-2018.2-caffe-mls-1.4:latest \ + durgabhavaniv/xilinx-ml_suite:latest \ bash From 846a1f24d31330c281e7b9457eafedee5899c1ac Mon Sep 17 00:00:00 2001 From: durgabhavaniv <42232855+durgabhavaniv@users.noreply.github.com> Date: Thu, 1 Aug 2019 17:53:55 +0530 Subject: [PATCH 6/7] Update app.py --- examples/caffe/REST/app.py | 45 ++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/examples/caffe/REST/app.py b/examples/caffe/REST/app.py index 263b8e8f5..2c0d1881f 100755 --- a/examples/caffe/REST/app.py +++ b/examples/caffe/REST/app.py @@ -7,13 +7,13 @@ import io app = flask.Flask(__name__) - + def LoadImage(prototxt,caffemodel,labels): import numpy as np import xdnn_io global net net = caffe.Net(prototxt,caffemodel,caffe.TEST) - return net + return net def InferImage(net,image,labels): import numpy as np @@ -36,50 +36,57 @@ def InferImage(net,image,labels): pass Labels = xdnn_io.get_labels(labels) xdnn_io.printClassification(softmax,[image],Labels) - return xdnn_io.getClassification(softmax,[image],Labels) + return xdnn_io.getClassification(softmax,[image],Labels) + +#@app.route('/predict', methods=['GET','POST']) # go through link http://172.24.157.249:5000/predict for result -@app.route("/predict", methods=["POST"]) +@app.route('/') # go through link http://172.24.157.249:5000/ for result def predict(): data = {"success": False} global prototxt global model global synset_words + global image - if flask.request.method == "POST": - image = flask.request.files["image"] - response = InferImage(net, image, synset_words) - data["success"] = True - data["response"] = response + response = InferImage(net, image, synset_words) + data["success"] = True + data["response"] = response return flask.jsonify(data) if __name__ == "__main__": parser = argparse.ArgumentParser(description='pyXFDNN') - parser.add_argument('--caffemodel', default="/opt/models/caffe/bvlc_googlenet/bvlc_googlenet.caffemodel", help='path to caffemodel file eg: /opt/models/caffe/bvlc_googlenet/bvlc_googlenet.caffemodel') - parser.add_argument('--prototxt', default="xfdnn_auto_cut_deploy.prototxt", help='path to prototxt file eg: xfdnn_auto_cut_deploy.prototxt') - parser.add_argument('--synset_words', default="$HOME/CK-TOOLS/dataset-imagenet-ilsvrc2012-aux/synset_words.txt", help='path to synset_words eg: $HOME/CK-TOOLS/dataset-imagenet-ilsvrc2012-aux/synset_words.txt') + parser.add_argument('--caffemodel', default="/opt/ml-suite/share/quantize_results/deploy.caffemodel", help='path to caffe model file eg: /opt/models/caffe/bvlc_googlenet/bvlc_googlenet.caffemodel') + parser.add_argument('--prototxt', default="/opt/ml-suite/share/xfdnn_auto_cut_deploy.prototxt", help='path to prototxt file eg: xfdnn_auto_cut_deploy.prototxt') + parser.add_argument('--synset_words', default="/opt/ml-suite/examples/deployment_modes/synset_words.txt", help='path to synset_words eg: $HOME/CK-TOOLS/dataset-imagenet-ilsvrc2012-aux/synset_words.txt') parser.add_argument('--port', default=5000) - + parser.add_argument('--image', default="/opt/ml-suite/examples/deployment_modes/dog.jpg") + args = vars(parser.parse_args()) if args["caffemodel"]: model=args["caffemodel"] - + if args["prototxt"]: prototxt=args["prototxt"] if args["synset_words"]: synset_words=args["synset_words"] - + + if args["image"]: + image=args["image"] + if args["port"]: port=args["port"] else: - port=9000 + port=9000 print("Loading FPGA with image...") net = LoadImage(prototxt, model, synset_words) - - print("Starting Flask Server...") - app.run(port=port) + #print("infering the image") + #InferImage(net,image,synset_words) + + print("Starting Flask Server...") + app.run(port=port,host='0.0.0.0') From 2209d913e9bc0fc097bc4a4af1f7c3cc681b8823 Mon Sep 17 00:00:00 2001 From: durgabhavaniv <42232855+durgabhavaniv@users.noreply.github.com> Date: Thu, 1 Aug 2019 18:01:20 +0530 Subject: [PATCH 7/7] Update run.sh --- examples/caffe/REST/run.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/caffe/REST/run.sh b/examples/caffe/REST/run.sh index caec3f57f..3bdb66b46 100755 --- a/examples/caffe/REST/run.sh +++ b/examples/caffe/REST/run.sh @@ -14,6 +14,4 @@ PORT="5000" python ../run.py --prototxt ${MODEL_PROTOTXT} --caffemodel ${MODEL_WEIGHTS} --prepare -python app.py --caffemodel ${MODEL_WEIGHTS} --prototxt xfdnn_auto_cut_deploy.prototxt --synset_words ${LABELS} --port ${PORT} - - +python app.py