QuickScorer
was designed by Lucchese, C., Nardini, F. M., Orlando, S., Perego, R., Tonellotto, N., and Venturini, R. with the support of Tiscali S.p.A.
It adopts a novel bitvector representation of the tree-based ranking model, and performs an interleaved traversal of the ensemble by means of simple logical bitwise operations. The performance of the proposed algorithm are unprecedented, due to its cache-aware approach, both in terms of data layout and access patterns, and to a control flow that entails very low branch mis-prediction rates.
All the nodes whose Boolean conditions evaluate to False are called false nodes, and true nodes otherwise.
The scoring of a document represented by a feature vector
The building block of this approach is an alternative method for tree traversal based on bit-vector computations
.
Given a tree and a vector of document features,
this traversal processes all its nodes and produces a bitvector
which encodes the exit leaf for the given document.
Given an input feature vector
The second refinement implements the operations on logical AND
between
One important result is that Quick Scorer
computes
Quick Scorer
updates a bitvector associated with Quick Scorer
maintains for each tree
ALGORITHM 1: Scoring a feature vector
-
Input:
-
$x$ : input feature vector -
$T_h = (N_h, L_h)$ : binary decision tree, with-
$N_h = {n_0, n_1, \cdots}$ : internal nodes of$T_h$ -
$L_h = {l_0, l_1, \cdots}$ : leaves of$T_h$ -
$n.mask$ : node bit mask associated with$n\in N_h$ -
$l_j.val$ : score contribution associated with leaf$l_j\in L_h$
-
-
-
Output:
- tree traversal output value
-
$score(x, T_h)$ :$\text{leaf_index}_h\leftarrow (1,1,\dots, 1)$ $U\leftarrow FindFalse(x, T_h)$ -
foreach node
$n \in U$ do$\text{leaf_index}_h\leftarrow \text{leaf_index}_h\land n.mask$
$j \leftarrow\text{index of leftmost bit set to 1 of leaf_index}_h$ -
return
$l_j.val$
ALGORITHM 2: : The QUICKSCORER Algorithm
-
Input:
-
$x$ : input feature vector -
$\mathcal T$ : ensemble of binary decision trees, with-
${w_0, w_1, \cdots, w_{|\mathcal{T}|-1}}$ : weights, one per tree -
$thresholds$ : sorted sublists of thresholds, one sublist per feature -
$treeids$ : tree’s ids, one per node/threshold -
$nodemasks$ : node bit masks, one per node/threshold -
$offsets$ : offsets of the blocks of triples -
$leafindexes$ : result bitvectors, one per each tree -
$leafvalues$ : score contributions, one per each tree leaf
-
-
-
Output:
- final score of
$x$
- final score of
-
$\text{QUICKSCORER}(x, T_h)$ :-
foreach node
$h \in {0,1\cdots, |T|-1}$ do$\text{leaf_index}_h\leftarrow (1,1,\dots, 1)$
-
foreach node
$k \in {0,1\cdots, |\mathcal{F}|-1}$ do$i\leftarrow offsets[k]$ $end\leftarrow offsetsets[k+1]$ -
while
$x[k] > thresholds[i]$ do$h \leftarrow treeids[i]$ $\text { leafindexes }[h] \leftarrow \text { leafindexes }[h] \wedge \text { nodemasks }[i]$ $i\leftarrow i+1$ -
if
$i\geq end$ then- break
$score \leftarrow 0$ -
foreach node
$h \in {0,1\cdots, |T|-1}$ do$j \leftarrow \text { index of leftmost bit set to 1 of},, {leafindexes }[h]$ $l \leftarrow h \cdot| L_{h} |+j$ $\text { score } \leftarrow \text { score }+w_{h} \cdot \text { leafvalues }[l]$
-
return
$score$
-
foreach node
- QuickScorer: a fast algorithm to rank documents with additive ensembles of regression trees
- Official repository of Quickscorer
- QuickScorer: Efficient Traversal of Large Ensembles of Decision Trees
- Fast Ranking with Additive Ensembles of Oblivious and Non-Oblivious Regression Trees
- Tree traversal
- https://github.com/hpclab/gpu-quickscorer
- https://github.com/hpclab/multithread-quickscorer
- https://github.com/hpclab/vectorized-quickscorer
- https://patents.google.com/patent/WO2016203501A1/en