diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index aa79ca96b58f2fdccf79d81c15fc63ab57c04645..0000000000000000000000000000000000000000 --- a/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM tensorflow/tensorflow:latest-gpu-py3 - -MAINTAINER Carlos de Lannoy <cvdelannoy@gmail.com> - -ADD . /baseless diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4929843ea84fc9eb8f21b6fdf7bb3a55a7f42201 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# baseLess: minION sequence detection, no basecalling required + +## Running on Nvidia Jetson Nano (2GB) +The Nvidia Jetson Nano is a single-board computer with dedicated GPU. Designed to be baseLess is light enough to run on + +Before first usage open a terminal in the baseless directory and build the image: + +```shell +docker build -f Dockerfile_jetson -t baseless . +``` + +open the docker container interactively: +```shell +docker run -it --rm --runtime nvidia --network host baseless +``` +Add any directories you may want to read/write by adding `-v /local/dir:/home/some_dir_name ` + +You can now start running inference! As the Jetson Nano has little memory to spare (2GB or 4GB, depending on your model), you may need to limit memory using the `--mem` option. We found that the 2GB model runs well with 512mb (`--mem 512`). + +## Jetson nano tips +- To free up some memory for smoother running, switch off the GUI -- `sudo systemctl stop lxdm` or `sudo sysctl disable lxdm` to prevent the GUI starting at startup. You can also follow Zafer Arican's [advice](https://www.zaferarican.com/post/how-to-save-1gb-memory-on-jetson-nano-by-installing-lubuntu-desktop) and switch to lubuntu. \ No newline at end of file diff --git a/inference/tf2tflite.py b/inference/tf2tflite.py index 2b8a7816733ea8c11df5c371237d90893a2568c8..d861e37d814a30948cd67d63c01bddf12c7d2b4f 100644 --- a/inference/tf2tflite.py +++ b/inference/tf2tflite.py @@ -1,4 +1,4 @@ -import argparse, re, h5py, sys, json +import argparse, re, h5py, sys, json, yaml from pathlib import Path from tempfile import TemporaryDirectory @@ -7,29 +7,51 @@ import numpy as np sys.path.append(f'{list(Path(__file__).resolve().parents)[1]}') from low_requirement_helper_functions import parse_output_path +from db_building.TrainingRead import Read +def rolling_window(array, window_size,freq): + shape = (array.shape[0] - window_size + 1, window_size) + strides = (array.strides[0],) + array.strides + rolled = np.lib.stride_tricks.as_strided(array, shape=shape, strides=strides) + return rolled[np.arange(0,shape[0],freq)] + + +def load_reads(fast5_path, bs, stride, filter_width): + raw_list = [] + for read_fn in Path(fast5_path).iterdir(): + if read_fn.suffix != '.fast5': + continue + with h5py.File(read_fn, 'r') as fh: raw = Read(fh, 'median').raw + raw_strided = rolling_window(raw, filter_width, stride) + raw_list.append(raw_strided) + raw_array = np.vstack(raw_list) + raw_list = np.array_split(raw_array, np.arange(0,len(raw_array), bs), axis=0) + raw_list = [np.expand_dims(rl,-1).astype(np.float32) for rl in raw_list if rl.shape == (bs, filter_width)] + return raw_list + parser = argparse.ArgumentParser(description='Convert baseLess h5 model to tf lite model for efficiency') parser.add_argument('--fp-precision', type=int, choices=[8, 16,32], default=32, help='Floating point precision for output model: 8, 16 or 32 bit [default: 32]') -parser.add_argument('--example-read', type=str, required=True) +parser.add_argument('--param-file', type=str, required=True) +parser.add_argument('--example-reads', type=str, required=True) parser.add_argument('--model', type=str, required=True, help='h5-format input model') parser.add_argument('--out-model', type=str, required=True) args = parser.parse_args() # --- parameter parsing --- +with open(args.param_file, 'r') as fh: + param_dict = yaml.load(fh, yaml.FullLoader) out_model = parse_output_path(args.out_model) -example_read = np.load(args.example_read).astype(np.float32) -def representative_dataset(): - for _ in range(100): - data = example_read - yield [data] -# if args.precision == 32: -# tf_dtype=tf.float +example_reads_list = load_reads(args.example_reads, param_dict['batch_size'], + param_dict['filter_stride'], param_dict['filter_width']) +def representative_dataset(): + for batch in example_reads_list: + yield [batch] # --- load and convert model --- mod = tf.keras.models.load_model(args.model) @@ -60,7 +82,7 @@ with TemporaryDirectory() as td: ) converter = tf.lite.TFLiteConverter.from_saved_model(td) converter.optimizations = [tf.lite.Optimize.DEFAULT] - converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] + # converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] converter.representative_dataset = representative_dataset converter.inference_input_type = tf.int8 # or tf.uint8 converter.inference_output_type = tf.int8 # or tf.uint8