Code Monkey home page Code Monkey logo

featurebroker's Introduction

Introduction

Welcome to the Resonance project. The purpose of this project is to enable the utilization of machine learning models across components and platforms.

It includes the notion of a feature broker, a library that enables sharing of context/features across code components, as well as providing a common abstraction layer for machine learning models. The core library includes the central interfaces and abstractions. Particular model implementations are available as specialized auxiliary libraries for:

  1. Vowpal Wabbit models via VW Slim,
  2. ONNX models,
  3. Azure Personalization Service (APS) models.

Note that while the library was originally intended to service asynchronous scenarios across different components, the API also supports efficient single-component single-thread inferencing as well. The abstraction for models is also implementable so other types of models can be plugged in to be used through the common API beyond the examples above.

Building

Let's imagine you've cloned the repo.

git submodule update --init --recursive

This will fetch the submodules.

You can then set up your build environment.

cmake . -B build.d

This will construct the platform specific build environment. For example, on Windows with a properly configured Visual Studio, this will create in the directory build.d the solution file Resonance.sln.

Example

The following example is adapted from our RunMatrixMultiply test of our ONNX model support. As the name suggests, this is a test of a model with a single ONNX MatMul operator over two inputs. This class is one of two built-in implementations of inference::Model. ONNX models contain within themselves a description of their input and output schemas, including their types. This example is structured more for simplicity of illustrating the key structures, rather complete coverage.

First, we start with a pre-amble where we simply load the model.

auto path = test_dir_path + "matmul.onnx";
auto modelExpected = onnx_model::Model::Load(path);
auto model = modelExpected.value();

Note that in this first phase we are loading a model. This code is peculiar to the onnx_model namespace, but we already see some common conventions emerge. In particular, throughout this codebase there is a lot of usage of things like tl::expected<T, std::error_code> for code that might fail. (In this case, T would be a std::shared_ptr<Model>.) One can read more about this structure here.

Throughout this code you'll note that we are living very dangerously, by not actually checking to see whether the tl::expected actually has the values we expect. In real production code a user would want to check and provide the remediation that is appropriate for their library (whether that is raising an exception, returning an error code, or something else is up to the user).

The particular model that is being loaded is an ONNX model that takes two placeholders (in the ONNX model sense) named A and B, and produces another output C, that is the result of performing a matrix multiplication of those two inputs.

FeatureBroker fb(model);
// Binding inputs and binding outputs.
auto inputA = fb.BindInput<Tensor<double>>("A:0").value_or(nullptr);
auto inputB = fb.BindInput<Tensor<double>>("B:0").value_or(nullptr);
auto output = fb.BindOutput<Tensor<double>>("C:0").value_or(nullptr);

In this particular section we create the FeatureBroker and associate it with a model in the first step. The inputs and outputs are bound, fed, and consumed in all the same function so it is simplest to do things that way.

In other scenarios, especially when multiple models are being used for inference, it is often common to create a feature broker without any model at all, bind inputs to that, and then later on the actual inferencing component .Forks another feature broker as a "child" of that feature broker, and binds an input. But in this simple example we are simply doing everything all at once.

Note again the usage of tl::expected for both the input and output pipe bindings, since bindings can fail due to a variety of factors. (But in this case, they do not, because the inputs and outputs happen to match the types advertised by the model.)

auto adata = std::shared_ptr<double>(new double[6]{1, 2, 3, 4, 5, 6});
auto bdata = std::shared_ptr<double>(new double[12]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
Tensor<double> a(adata, {2, 3});
Tensor<double> b(bdata, {3, 4});
inputA->Feed(a);
inputB->Feed(b);
Tensor<double> c;
auto updateExpected = output->UpdateIfChanged(c);
// This should be an tl::expected<bool, ...>, where there is no error and the value is true.
const double* cdata = c.Data();

// C should contain the values as indicated in the last value:
//
//       / 1 2 3 \ / 1  2  3  4 \   / 38 44  50  56 \
// A B = \ 4 5 6 / | 5  6  7  8 | = \ 83 98 113 128 /
//                 \ 9 10 11 12 /

Note that the Feed operation here succeeds unconditionally. This is important. One of the chief design considerations is that components that feed values used in inference did not want to have to deal with failure on account of not being what the model expected, or anything else which is practically always outside of their control. This is part of the design goal of giving feature providing components as little trouble as possible. So long as it is the right type, a Feed call will succeed. Any bad forms would have to be detected and handled downstream by the inferencing component.

Speaking of the inferencing component, let us move on to UpdateIfChanged. This method returns a tl::expected<bool, ...> structure. An error might occur for any reason defined by the library. In this case, to give a specific example, an error would arise if the bound input matrices were not of compatible dimension.)

Note also the use of inference::Tensor<T> in this code. Crucially, while the library does provide a simple wrapping Tensor object, this is not prescriptive: the FeatureBroker library is unopinionated w.r.t. what types are allowed, assuming that in the compilation of C++ used std::type_info is supported.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

featurebroker's People

Contributors

microsoft-github-operations[bot] avatar microsoftopensource avatar singlis avatar tomfinley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

featurebroker's Issues

VW Remote needs a client stub to enable building the vw remote project

Since the vw remote project has a dependency on cpp rest through vcpkg, its not part of the normal build. This is a problem as further code changes happen as its easy to forget to test the vw_remote code. Therefore, this is an issue to create a stub client implementation that is used by default and enable the vw_remote project permanently.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.