diff options
Diffstat (limited to 'nnpackage/spec')
-rw-r--r-- | nnpackage/spec/00_requirement.md | 28 | ||||
-rw-r--r-- | nnpackage/spec/10_packaging_and_manifest.md | 92 | ||||
-rw-r--r-- | nnpackage/spec/20_model_and_operators.md | 90 | ||||
-rw-r--r-- | nnpackage/spec/30_custom_op.md | 86 |
4 files changed, 296 insertions, 0 deletions
diff --git a/nnpackage/spec/00_requirement.md b/nnpackage/spec/00_requirement.md new file mode 100644 index 000000000..035fc9856 --- /dev/null +++ b/nnpackage/spec/00_requirement.md @@ -0,0 +1,28 @@ +# Requirements (or Checkpoint) + +## Packaging + +### Packaging Format + +- [ ] PF1. support royalty free compression +- [ ] PF2. compatible with low end devices + +### Manifest + +- [ ] MF1. human readable +- [ ] MF2. easy to parse for several types of configuration variables. +- [ ] MF3. small binary size for parsing (since the parser will be part of runtime) + +## Model + +- [ ] MD1. support multiple tensor layout (such as NHWC, NCHW, etc) + - define layout for model / submodel / other unit? + - use operator (such as loco) +- [ ] MD2. describe operand? + - include in operator vs. independent field for operand + - support unspecified dimension value & unspecified rank? +- [ ] MD3. describe operation type + - string vs. enum value? +- [ ] MD4. support many quantization + - howto (ex. union type quantization parameter field, field handle quantization parameter table for quantization methodology) +- [ ] MD5. backward-compatibility and maintainability diff --git a/nnpackage/spec/10_packaging_and_manifest.md b/nnpackage/spec/10_packaging_and_manifest.md new file mode 100644 index 000000000..1bc18ff30 --- /dev/null +++ b/nnpackage/spec/10_packaging_and_manifest.md @@ -0,0 +1,92 @@ +# Packaging and Manifest + +## 1. Overview + +`nnpackage` is the input of nnruntime(`neurun`), and the output of nncompiler(`nncc`). + +`nnpackage` contains all data (such as model, `MANIFEST`, custom_op) that requires to run a given model. + +The document will cover packaging and `MANIFEST` only. + +For `model` and `custom_op`, see [20_model_and_operators.md](20_model_and_operators.md) and [30_custom_op.md](30_custom_op.md). + +## 2. Packaging Structure + +`nnpackage` is a Zip archive in the following structure: + +``` +nnpackage +├── custom_op +├── metadata +│ └── MANIFEST +└── mymodel.model +``` + +- `mymodel.model` is a model file that has computation graph and weights. +- `metadata` is a directory that contains all metadata including `MANIFEST`. +- `MANIFEST` is a collection of attributes about this package. +- `custom_op` is a directory that contains implementation objects. + +## 3. Packaging Format + +`nnpackage` is contained in `Zip Archive`, which could be either `compressed` or `stored` (no compression). + +## 4. Manifest + +`MANIFEST` is a collection of attributes about `nnpacakge`. + +### Attributes + +#### version + +`version` is composed of 3 numbers in `MAJOR`.`MINOR`.`PATCH`. + +Given a version number MAJOR.MINOR.PATCH, increment the: + +MAJOR version when you make incompatible/breaking changes, +MINOR version when you add functionality in a backwards-compatible manner, and +PATCH version when you make backwards-compatible bug fixes. + +For detail, see [semantic versioning 2.0.0](https://semver.org/) + +##### major-version + +`major-version` is the major version of `nnpackage`. + +##### minor-version + +`minor-version` is the minor version of `nnpackage`. + +##### patch-version + +`patch-version` is the patch version of `nnpackage`. + +#### models + +`models` is an array of path to model files, which is relative path from top level directory of this package. +The first element from the array will be the default model to be executed. + +#### model-types + +`model-types` is an array of strings that describes the type of each model in `models`. + +It can have the values (case-sensitive) in following table. + +| name | description | +|--------|------------------------| +| tflite | tensorflow lite schema | +| circle | nnpackage schema | + +### Example + +Here is an example of `MANIFEST`. + +``` +{ + "major-version" : "1", + "minor-version" : "0", + "patch-version" : "0", + "models" : [ "mymodel.model", "yourmodel.model" ], + "model-types" : [ "tflite", "circle" ] +} +``` diff --git a/nnpackage/spec/20_model_and_operators.md b/nnpackage/spec/20_model_and_operators.md new file mode 100644 index 000000000..fa4131645 --- /dev/null +++ b/nnpackage/spec/20_model_and_operators.md @@ -0,0 +1,90 @@ +# Model + +## Serialization Format + +`nnpackage` uses flatbuffers to store model. + +Rationale: + +1. `flatbuffers` is: + +- space-efficient +- explicit-schema based +- royalty-free license open-source library +- header-only solution (unless we use flatbuffer's reflection) +- proven solution (used by TensorFlow-Lite) + +2. We've checked other solutions: +- [`bjson (binary JSON)`](http://bjson.org/) +- `protocol buffers` + +## Baseline Schema + +`nnpackage` schema is based on tensorflow-lite schema. + +Rationale: + +- Fundamentally, `nnpackage` and `TFLite` have same aim: +Running pre-trained models on a device, which has relatively low computing power and memory. +TFLite's solution is acceptable, we don't need to create same thing again. +- We can use several infra-structures and tools from TFLite. + +## Extensions + +`nnpackage` model has some extensions that are different or missing from TFLite. + +### Multiple Layout + +`nnpackage` can support multiple layouts. + +1. The layout is presented using `DataFormat` enumeration. + +`DataFormat` must be one of the enumeration defined in `nnpackage_schema.fbs`. + +For example, `CHANNELS_FIRST` or `CHANNELS_LAST` can be used. + +``` + // For 2D data, NHWC(batch, height, width, channels) + // For 3D data, NDHWC(batch, depth, height, width, channels) + CHANNELS_LAST = 0, + // For 2D data, NCHW(batch, channels, height, width) + // For 3D data, NCDHW(batch, channels, depth, height, width) + CHANNELS_FIRST = 1, +``` + +2. `DataFormat` must be same within a submodel. + +Rationale: + +- frequent switching between different layout degrades the performance + +Under this assumption, We expect to + +- simplify the runtime implementation +- accelerate the performance +- reduce the memory usage + +### Unspecified Dimension + +`nnpackage` represents unspecified dimension with `-1`. + +Rationale: + +1. It should be `int` since dimension is int type flatbuffer schema. Thus '?' cannot be used. +2. `0` is also a candidate, which is used for Android NN API. +However, we would like to reserve `0` because `0` could be a valid dimension for a certain +operator (e.g. `tflite.slice`). + +## Operator Reference + +All operators use same semantics of tensorflow lite operators. +Refer tensorflow lite source code to understand what inputs, outputs and attributes +are required and how they are interpretered. + +## Schema Source + +nnpackage supports two kinds of models: `tflite` and `circle` + +- For tflite, see `schema.fbs` from tensorflow lite source. + +- For circle, see [`../schema/circle_schema.fbs`](../schema/circle_schema.fbs). diff --git a/nnpackage/spec/30_custom_op.md b/nnpackage/spec/30_custom_op.md new file mode 100644 index 000000000..58e0acddb --- /dev/null +++ b/nnpackage/spec/30_custom_op.md @@ -0,0 +1,86 @@ +# Custom Operators + +This document explains about custom operator and how custom op is represented in nnpackage. + +## What is custom operator? + +Custom operator(hereafter custom op) is used to provide a new operator implementation. +It can be anything that does not exist in current runtime implementation. + +You can use custom operator for several use cases, possible use cases are: + +- when an operator in tensorflow is not supported in nnfw runtime +- when an operator is supported, however, you would like to use your own implementation + - it may be for optimization, by grouping several operators into one super operator. + +## Custom op in model + +nnpackage will support several kinds of models. +Currently the only type is tflite. + +### tflite + +If you're using `tflite` format, it is same format to tensorflow lite. + +You can generate `tflite` model with custom op using `tflite_convert`. +Please find the documentation in tensorflow official site. + +## Custom op kernel implementation + +You need to provide the kernel of custom op in the following form: + +``` +/* + * Custom kernel evaluation function + * + * param[in] params custom operation parameters + * param[in] userdata pointer to user-specified buffer( kernel instance specific ) + */ +typedef void (*nnfw_custom_eval)(nnfw_custom_kernel_params *params, char *userdata, + size_t userdata_size); + +``` + +The structures and relevant APIs are defined in nnfw APIs. +Please see `nnfw_dev.h` for detail. + +You can find example in `nnfw` repository. + +Custom op kernel implementation is stored in nnpackage in form of prebuilt library. + +It is example nnpackage structure for `FillFrom`: + +``` +FillFrom +├── FillFrom.tflite +├── custom_op +│ ├── libFillFrom.armv7l-linux.debug.a +│ └── libFillFrom.armv7l-linux.release.a +└── metadata + └── MANIFEST +``` + +All custom operator libraries are put under `{nnpackage_root}/custom_op/lib{customop_name}.{arch}-{os}-{buildtype}.a`. + +## How to use custom op in app + +To use custom op, the app has to register the operators with `nnfw_register_custom_op_info`. + + +``` +/* + * custom operation registration info + */ +typedef struct +{ + nnfw_custom_eval eval_function; +} custom_kernel_registration_info; + +NNFW_STATUS nnfw_register_custom_op_info(nnfw_session *session, const char *id, + custom_kernel_registration_info *info) +``` + +Please find sample app in `nnfw` repository + +The `id` should be unique in an app. + |