Get started Features Tutorials Blog Research
November 12, 2020

VowpalWabbit 8.9.0 Release Notes

author's avatar
Jack Gerrits

It’s been a while since we last released, but a lot of exciting things have been going on!

Let’s take a look at some of the big items from this release.

Python Wheels

We now produce Python wheels for most platforms which are uploaded to PyPi. This means you almost never have to build from source to use VW in Python! We’re committed to making using VW in Python a great experience, and this is just the first step.

String feature values in text format

In a small expansion of the text format you can now supply a string as the value for a feature. This strictly adds a case which is now valid and doesn’t affect any existing valid data files. If this was tried previously you’d receive a malformed example warning and the feature would be skipped. When a feature value is supplied in this way the hash is now calculated as hash(feature_value, hash(feature_name, namespace_hash)) where hash’s signature is hash(input, seed). This chained hashing is denoted by a ^ in the audit output.

echo "| myname:myvalue" | vw --audit


Num weight bits = 18 learning rate = 0.5 initial_t = 0 power_t = 0.5 using no cache Reading datafile = num sources = 1 Enabled reductions: gd, scorer average since example example current current current loss last counter weight label predict features 0 myname^myvalue:112555:1:0@0 Constant:116060:1:0@0 n.a. n.a. 1 1.0 unknown 0.0000 2

finished run number of examples = 1 weighted example sum = 1.000000 weighted label sum = 0.000000 average loss = n.a. total feature number = 2

Continuous Actions

CATS is a contextual bandit algorithm with a continuous action space. It uses epsilon greedy exploration with tree policy classes and smoothing.

CATS, utilizing the features given as input, will first choose a center from a continuous action range using a tree policy, and then will use a bandwidth to determine a radius of randomization around the chosen center (centers or discrete actions). The depth of the tree and the bandwidth need to be specified beforehand.

Thanks to Maryam Majzoubi (@mmajzoubi) for this contribution.

Square CB

Square CB is a new exploration algorithm for contextual bandits which works by reducing contextual bandits to regression. It is the first reduction of this type that provably has optimal performance for contextual bandits, and has comparable runtime to other basic exploration algorithms such as epsilon-greedy. Empirically, it has been shown that it has competitive performance on the large-scale evaluation setup from the bake-off paper.

Thanks to Dylan Foster (@canondetortugas) for this contribution.

Probabilistic Label Tree

Probabilistic label tree is a new reduction for logarithmic time multilabel classification. It is especially useful when there is a large number of classes, around 10000 or more.

Thanks to Marek Wydmuch (@mwydmuch) for this contribution.


Slates is a multi slot algorithm which builds upon the ideas of Conditional Contextual Bandit. It adds the following constraints:

  1. There is a single global reward
  2. Slots have disjoint action sets

Contextual Bandit Distributionally Robust Optimization

This reduction adds support for distributionally robust optimization for contextual bandits in VW.

CB Explore ADF RND

This adds a new exploration algorithm for CB ADF inspired by random network distillation.

Initial Pandas support in Python

We introduced in this release DFtoVW, a class that converts pandas.DataFrame object into VW input format. To use import it from vowpalwabbit.DFtoVW. We currently support simple label, multiclass label and feature transformations.


from vowpalwabbit.DFtoVW import DFtoVW, SimpleLabel, Feature, Namespace
import pandas as pd

df = pd.DataFrame({"y": [1, -1], "a": [2, 3], "b": [3, 2]})
conv1 = DFtoVW(df=df,
    features=[Feature("a"), Feature("b")])
# ['1 | a:2 b:3', '-1 | a:3 b:2']

conv2 = DFtoVW(df=df,
    namespaces=[Namespace(name="ns1", features=Feature("a"))])
# ['1 |ns1 a:2', '-1 |ns1 a:3']

Thanks to Etienne Kintzler (@etiennekintzler) for this contribution.

New options


In the JSON and DSJSON formats when a string was supplied as a value the old behavior was to concatenate the property name with the value. This option changes the behavior to hash the feature name a long with the value to determine the feature index. The old behavior is deprecated and you’ll receive a warning if --chain_hash is not supplied and you are using either --json or --dsjson. The old behavior will be removed in a future version.


When a model is saved in active learning mode, it resumes active learning when loaded (i.e., it starts listening for input on a port and ignoring local sources). This option allows the user to change this behaviour (so that the Python library can interact with the loaded model, for example).

Contributed by @zechyw.


This option will skip running the driver. It is especially helpful with the new diagnostic about enabled reductions.


vw --ccb_explore_adf --dry_run


Num weight bits = 18 learning rate = 0.5 initial_t = 0 power_t = 0.5 using no cache Reading datafile = num sources = 1 Enabled reductions: gd, scorer, csoaa_ldf, cb_adf, cb_explore_adf_greedy, cb_sample, shared_feature_merger, ccb_explore_adf

finished run number of examples = 0 weighted example sum = 0.000000 weighted label sum = 0.000000 average loss = n.a. total feature number = 0


This option was added to cb_explore with cover so that it can behave the same way as cb_explore_adf_cover which provides a switch for turning off the uniform exploration on zero-probability actions. Uniform exploration on zero-probability actions is now on by default in cb cover to match the existing behavior of cb_explore_adf_cover.

Other improvements

Thank you

A huge thank you and welcome to all of the new contributors since the last release:

And of course thank you to existing contributors:

Full changelist