The primary way to create a Rune is by using a text file in the YAML format, referred to as a Runefile, to declare how a machine learning pipeline is configured.
A typical Runefile.
The sections on this reference page are organized to reflect the structure of the Runefile itself.
The first item in a Runefile is the
image. This specifies the functionality
that will be provided to the Rune by the runtime.
The only image supported at the moment is
The main concept in a Runefile is that of the "pipeline". This is a directed acyclic graph specifying how data is transformed as it passes through the Rune.
pipeline is a dictionary of key-value pairs where the key attaches a name
to a particular stage.
There are several types of stages, but most will share some common properties.
A stage may specify
args that can be used to modify how data is generated or
transformed. This is a free-form dictionary of key-value pairs where the value
can be a primitive type (e.g. numbers and strings) or a list of primitive types.
Examples of this may be providing the sample rate to an audio capability or the list of labels to use when classifying.
For more advanced use cases like using a well-known enum or calculated
expressions, a "verbatim" argument value may be used. This is a string
containing valid Rust syntax, prefixed with an
@ symbol (e.g.
inputs property contains a list of strings specifying which stages a
particular stage may receive input from. This is typically just the stage's
name, but in cases when a stage may have multiple outputs the desired output
may be specified using dot syntax.
Here is an example where the
debug stage accepts data from
rand and the
outputs 0 and 1 from the
Each stage which outputs data must specify the type of that data using the
outputs property. This specifies the data type and shape of a tensor.
A stage may have multiple outputs. For example, if using a proc block to classify the two most confident inputs and return both the labels and confidence values.
Supported types are:
|Integer||An 8-bit unsigned integer|
|Integer||An 8-bit signed integer|
|Integer||A 16-bit unsigned integer|
|Integer||A 16-bit signed integer|
|Integer||A 32-bit unsigned integer|
|Integer||A 32-bit signed integer|
|Integer||A 64-bit unsigned integer|
|Integer||A 64-bit signed integer|
|Float||A 32-bit floating point number|
|Float||A 64-bit floating point number|
|String||An arbitrary-length string constant|
dimensions property specifies the shape of a tensor (multi-dimensional
array) in row-major order.
A capability stage is how information from the outside world enters the Rune. This may take the form of an image from the device's camera or samples from an audio file.
Capabilities have the following properties:
Capabilities are specified using a
capability key which dictates what type
of capability it is.
Supported capability types are:
|Samples from an accelerometer as 3 `f32`s, X, Y, and Z.|
|random data generated from the runtime's random number generator|
|raw data from an opaque user-specified source|
|16-bit Pulse Code Modulated audio samples|
A model stage is specified by giving it a
property which points to the location of a TensorFlow Lite model on disk,
relative to the Runefile.
Models have the following properties:
A procedural block (aka "proc block") is a Rust crate which exposes
functionality for transforming data from one form to another. Proc block stages
are differentiated using a
The proc block identifier takes on the form,
path is the only required piece.
path piece may be interpreted slightly differently depending on its form:
- A single identifier (e.g.
rune-label-proc-block) is interpreted as a crate on crates.io
./points to a crate on disk relative to the Runefile
- A full URL is interpreted as the path to a git repository on the internet and will be used as a git dependency
- A path of the form
hotg-ai/runeis shorthand for a GitHub repository
More formally, a proc block path matches the following regex:
Common properties supported by proc blocks are:
Some well-known proc blocks are:
|Modulo||Calculates the modulus of each element in a tensor||(any)|
An output is the mechanism used to pass information processed by the Rune to the
outside world (e.g. the host application). Outputs are differentiated using a
output: serial property, where the value specifies the type of output.
Common properties supported by outputs are:
Some well-known outputs are:
|SERIAL||A user-defined component which accepts JSON-formatted UTF-8 strings||(any)|