November 9, 2016·4 min read·engineeringvalkeyredismodulesmachine-learning

Redis-ML moves trained model evaluation into Redis

Redis-ML stores operational prediction models as module data types. Spark can train the model while Redis exposes evaluation through commands available to application clients.

Training a model and answering an application request impose different requirements on a system. Redis-ML puts the prediction side inside Redis while leaving training with tools such as Apache Spark. The 9 November announcement describes saving Spark-generated models directly into Redis, then invoking module commands to evaluate them for interactive applications.

The significant change is the representation of the model in the serving system. Redis-ML does not merely save an opaque model file under a key and return it to an application. The module stores models as operational Redis data types and supplies commands that perform prediction or evaluation on those stored structures.

I like Redis's combination of explicit data structures and commands that act on them. Extending that model to prediction is interesting because an application can submit input to the stored model without implementing the model evaluator in every client language. The attraction depends on understanding which part of the machine-learning workflow moves into the database.

Spark still performs the training

The announcement describes the conventional Spark flow as training on historical data, saving the model to disk, and loading it later for prediction. Its proposed alternative retains Spark training. After training, the integration saves the model through Redis-ML so applications can request predictions against the in-memory representation.

This separates the computational responsibilities. Training derives a model from examples. Serving evaluates that model against new input. Redis-ML's command interface addresses the latter, so describing it as training machine-learning models inside Redis would misstate the announced workflow.

The contemporary Spark-Redis-ML README calls the package a way to load Spark ML models into Redis-ML. Its requirements include Spark 2.0 or later, an unstable-branch Redis build, Jedis, and Jedis-ML. The unstable-branch requirement is relevant to deployment maturity. This integration does not describe installing a module into an arbitrary existing stable Redis server.

The README also distinguishes the pieces needed on each side. Redis starts with the shared module loaded, while the Spark shell receives the integration and client jars. Exporting the trained model and evaluating it are related operations, but the application runtime and the training environment do not need to be the same process.

The stored value includes executable model structure

The module README available at the announcement lists decision-tree ensemble classification and regression. It also lists linear regression, logistic regression, and matrix operations. These capabilities have separate commands, which makes the model's supported operations visible in the database interface.

For forests, ml.forest.add supplies tree structure and ml.forest.run evaluates a data item. The documented example creates three trees with numeric decisions on feature 1, a threshold of 0.1, and leaf values. It then evaluates feature values on either side of that threshold and returns different classifications.

That example demonstrates the difference between storing a serialized object and exposing a model-aware command. The application sends a feature value and an evaluation mode to a named forest. The module already has the tree structure it needs to calculate the answer. A Redis client can issue the command without first downloading and reconstructing the forest in its own runtime.

The linear-regression example is shorter. After the module is loaded, the documented commands are:

ML.LINREG.SET a 2 3 4 5
ML.LINREG.PREDICT a 1 1 1

The README gives the prediction result as the string 14. This is a concrete command example from the module's current documentation. It does not imply support for arbitrary model serialization formats or every estimator available in Spark. Each supported model needs a representation and operations that Redis-ML implements.

Serving becomes a shared database operation

The announcement argues that Redis client libraries let applications in different languages access the same model. That is a useful consequence of exposing evaluation through commands. The server owns the stored representation, and clients exchange inputs and results through the database connection.

This can reduce duplicated serving implementations across applications. It also makes Redis and the module part of the request path for prediction. An application that previously loaded a local model now depends on access to the serving database. The change relocates evaluation and model state, so it changes the failure boundary as well as the programming interface.

The module README requires a BLAS library and gives ATLAS as the author's choice. It documents building the module and loading the resulting shared object with --loadmodule. Those details show that this is native server-side functionality with its own build dependencies. It is not simply a client library layered over existing string commands.

The module README identifies its license as AGPL. The module is a separate project with its own requirements, so adopting its commands also means evaluating that project as a dependency.

I find the shared command interface more persuasive than a general claim that databases should perform machine learning. It gives a specific reason to place evaluation near stored model state. The application gains a common evaluator, while the supported model types and the native module become explicit deployment choices.

The benchmark describes one reported workload

The announcement reports a Redis-team benchmark using about 1,000 models, each with about 15,000 trees generated through Spark ML's random-forest algorithm. Its table gives average classification times of 13 milliseconds for the comparison path and 1 millisecond for Redis-ML. The announcement also reports shorter model-save times and no separate load time for a model already in memory.

Those figures describe the vendor's reported workload. They do not establish the latency of every model or the cost of moving an application's inputs to the server. The mechanism behind the comparison is nevertheless concrete. Redis-ML keeps the serving representation in memory and evaluates it through model-specific commands, avoiding a separate model load on that path.

The practical contribution is a defined interface between training and serving. Spark builds a model, the integration loads supported model structures into Redis-ML, and application clients invoke prediction commands. The model remains a shared server-side value with operations implemented by the module, so clients can request evaluation without each maintaining an independent model interpreter.