From 3b2b2b191027336e99f9aef10c8a301d11182097 Mon Sep 17 00:00:00 2001 From: hussainsultan Date: Fri, 31 Jan 2025 17:29:31 -0500 Subject: [PATCH] docs: add udf rewriting blog post --- .../udf-rewriting/images/tree-pruning.png | Bin 0 -> 83307 bytes docs/posts/udf-rewriting/index.qmd | 417 ++++++++++++++++++ 2 files changed, 417 insertions(+) create mode 100644 docs/posts/udf-rewriting/images/tree-pruning.png create mode 100644 docs/posts/udf-rewriting/index.qmd diff --git a/docs/posts/udf-rewriting/images/tree-pruning.png b/docs/posts/udf-rewriting/images/tree-pruning.png new file mode 100644 index 0000000000000000000000000000000000000000..e9672dc4060e43d9f39106bcbc292da44d325b35 GIT binary patch literal 83307 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 +1` will never be evaluated. By **removing** that branch, the tree becomes +smaller and faster to evaluate—especially when you have hundreds of trees (as +in many gradient-boosted models). + +**Reference**: Check out the [Raven +optimizer](https://arxiv.org/pdf/2206.00136) paper. It demonstrates how you can +prune nodes in query plans for tree-based inference, so we’re taking a similar +approach here for **forests** (GBDTs) using **Ibis.** + + +### Quickgrove: prunable GBDT models + +Quickgrove is an experimental package that can load GBDT JSON models and +provides a `.prune(...)` API to remove unreachable branches. For example: + +```python +#pip install quickgrove +import quickgrove + +model = quickgrove.json_load("diamonds_model.json") # Load an XGBoost model +model.prune([quickgrove.Feature("color_i") < 0.2]) # Prune based on known predicate +``` + +Once pruned, the model is leaner to evaluate. Note: The results heavily depend on +model splits and interactions with predicate pushdowns. + + +## Scalar PyArrow UDFs in Ibis + +::: {.column-margin} +Please note that we are using our own modified DataFusion backend. The +DataFusion backend and DuckDB backend behave differently: DuckDB expects a +`ChunkedArray` while DataFusion UDFs expect `ArrayRef`. We are working on +extending quickgrove to work with the DuckDB backend. +::: + +We’ll define a simple Ibis UDF that calls our `model.predict_arrays` under the +hood: + +```python +import ibis +import ibis.expr.datatypes as dt + +ibis.set_backend("datafusion") +@ibis.udf.scalar.pyarrow +def predict_gbdt( + carat: dt.float64, + depth: dt.float64, + # ... other features ... +) -> dt.float32: + array_list = [carat, depth, ...] + return model.predict_arrays(array_list) +``` + +Currently, UDFs are opaque to Ibis. We need Ibis to teach Ibis how to rewrite a +udf based on predicates it knows about. + + +## Making Ibis UDFs predicate-aware + +Here’s the general process: + +1. **Collect predicates** from the user’s filter (e.g. `x < 0.3`). +2. **Prune** the model based on those predicates (removing unreachable tree + branches). +3. **Rewrite** a new UDF that references the pruned model, preserving the rest + of the query plan. + +### 1. Collecting predicates + +```python +from ibis.expr.operations import Filter, Less, Field, Literal +from typing import List, Dict + +def collect_predicates(filter_op: Filter) -> List[dict]: + """Extract 'column < value' predicates from a Filter operation.""" + predicates = [] + for pred in filter_op.predicates: + if isinstance(pred, Less) and isinstance(pred.left, Field): + if isinstance(pred.right, Literal): + predicates.append({ + "column": pred.left.name, + "op": "Less", + "value": pred.right.value + }) + return predicates +``` + +### 2. Pruning model and creating a new UDF + +```python +import functools +from ibis.expr.operations import ScalarUDF +from ibis.common.collections import FrozenDict + +def create_pruned_udf(original_udf, model, predicates): + """Create a new UDF using the pruned model based on the collected predicates.""" + from quickgrove import Feature + + # Prune the model + pruned_model = model.prune([ + Feature(pred["column"]) < pred["value"] + for pred in predicates + if pred["op"] == "Less" and pred["value"] is not None + ]) + # For simplicity, let’s assume we know the relevant features or keep them the same. + + def fn_from_arrays(*arrays): + return pruned_model.predict_arrays(list(arrays)) + + # Construct a dynamic UDF class + meta = { + "dtype": dt.float32, + "__input_type__": "pyarrow", + "__func__": property(lambda self: fn_from_arrays), + "__config__": FrozenDict(volatility="immutable"), + "__udf_namespace__": original_udf.__module_ + "__module__": original_udf.__module__, + "__func_name__": original_udf.__name__ + "_pruned" + } + + # Create a new ScalarUDF node type on the fly + node = type(original_udf.__name__ + "_pruned", (ScalarUDF,), {**fields, **meta}) + + @functools.wraps(fn_from_arrays) + def construct(*args, **kwargs): + return node(*args, **kwargs).to_expr() + + construct.fn = fn_from_arrays + return construct +``` + +### 3. Rewriting the plan + +Now we use an Ibis rewrite rule (or a custom function) to **detect filters** on +the expression, prune the model, and produce a new project/filter node. + +```python +from ibis.expr.operations import Project + +@replace(p.Filter) +def prune_gbdt_model(filter_op, original_udf, model): + """Rewrite rule to prune GBDT model based on filter predicates.""" + + predicates = collect_predicates(filter_op) + if not predicates: + # Nothing to prune if no relevant predicates + return filter_op + # in a real implementation you'd want to match on a ScalarUDF and ensure that the instance of the model type is + # the one implemented with quickgrove + pruned_udf, required_features = create_pruned_udf(original_udf, model, predicates) + + parent_op = filter_op.parent + # Build a new projection with the pruned UDF + new_values = {} + for name, value in parent_op.values.items(): + # If it’s the column that calls the UDF, swap with pruned version + if name == "prediction": + # For brevity, assume we pass the same columns to the pruned UDF + new_values[name] = pruned_udf(value.op().args[0], value.op().args[1]) + else: + new_values[name] = value + + new_project = Project(parent_op.parent, new_values) + + # Re-add the filter conditions on top + new_predicates = [] + for pred in filter_op.predicates: + if isinstance(pred, Less) and isinstance(pred.left, Field): + new_predicates.append( + Less(Field(new_project, pred.left.name), pred.right) + ) + else: + new_predicates.append(pred) + + return Filter(parent=new_project, predicates=new_predicates) +``` + +### Diff + +For a query like the following: + +```python +expr = ( + t.mutate(prediction=predict_gbdt(t.carat, t.depth, ...)) + .filter( + (t["clarity_vvs2"] < 1), + (t["color_i"] < 1), + (t["color_j"] < 1) + ) + .select("prediction") +) +``` +See the diff below: + +Notice that with pruning we can drop some of the projections in +the UDF e.g., `color_i`, `color_j` and `clarity_vvs2`. The underlying engine +(e.g., DataFusion) may optimize this further when pulling data for UDFs. We +cannot completely drop these from the query expression. + +```shell +- predict_gbdt_3( ++ predict_gbdt_pruned( + carat, depth, table, x, y, z, + cut_good, cut_ideal, cut_premium, cut_very_good, +- color_e, color_f, color_g, color_h, color_i, color_j, ++ color_e, color_f, color_g, color_h, + clarity_if, clarity_si1, clarity_si2, clarity_vs1, +- clarity_vs2, clarity_vvs1, clarity_vvs2 ++ clarity_vs2, clarity_vvs1 +) +``` + +## Putting it all together + +The complete example can be found [here](https://github.com/letsql/trusty/blob/main/python/examples/ibis_filter_condition.py). + +```python +# 1. Load your dataset into Ibis +t = ibis.read_csv("diamonds_data.csv") + +expr = ( + t.mutate(prediction=predict_gbdt(t.carat, t.depth, ...)) + .filter( + (t["clarity_vvs2"] < 1), + (t["color_i"] < 1), + (t["color_j"] < 1) + ) + .select("prediction") +) + +# 3. Apply your custom optimization +optimized_expr = prune_gbdt_model(expr.op(), predict_gbdt, model) + +# 4. Execute the optimized query +result = optimized_expr.to_expr().execute() +``` + +When this is done, the model inside `predict_gbdt` will be **pruned** based on +the expression's filter conditions. This can yield significant speedups on +large datasets (see @tbl-perf). + + +## Performance impact + +[Here](https://github.com/letsql/quickgrove/blob/main/python/examples/ibis_filter_condition_bench.py) +is the benchmark results ran on Apple M2 Mac Mini, 8 cores / 8GB Memory run +with a model trained with 100 trees and depth 6 with following filter +conditions: + +``` +_.carat < 1, +_.clarity_vvs2 < 1, +_.color_i < 1, +_.color_j < 1, +``` + +Benchmark results: + +| File Size | Regular (s) | Optimized (s) | Improvement | +| --- | --- | --- | --- | +| 5M | 0.82 ±0.02 | 0.67 ±0.02 | 18.0% | +| 25M | 4.16 ±0.01 | 3.46 ±0.05 | 16.7% | +| 100M | 16.80 ±0.17 | 14.07 ±0.11 | 16.3% | +: Performance improvements {#tbl-perf} + +**Key takeaway**: As data volume grows, skipping unneeded tree branches can +translate to real compute savings, albeit heavily dependent on how pertinent +the filter conditions might be. + + +## LetSQL: simplifying UDF rewriting + +[LetSQL](https://letsql.com/)) makes advanced UDF rewriting and multi-engine +pipelines much simpler. It builds on the same ideas we explored here but wraps +them in a higher-level API. + +Here’s a quick glimpse of how LetSQL might simplify the pattern: + +```python +# pip install letsql + +import letsql as ls +from letsql.expr.ml import make_quickgrove_udf, rewrite_quickgrove_expression + +model_path = "xgboost_model.json" +predict_udf = make_quickgrove_udf(model_path) + +t = ls.memtable(df).mutate(pred=predict_udf.on_expr).filter(ls._.carat < 1) +optimized_t = rewrite_quickgrove_expression(t) + +result = ls.execute(optimized_t) +``` +The complete example can be found +[here](https://github.com/letsql/letsql/blob/main/examples/quickgrove_udf.py). +With LetSQL, you get a **shorter, more declarative approach** to the same +optimization logic we manually coded with Ibis. It abstracts away the gritty +parts of rewriting your query plan. + + +## Best practices & considerations + +- **Predicate Types**: Currently, we demonstrated `column < value` logic. You +can extend it to handle `<=`, `>`, `BETWEEN`, or even categorical splits. +- **Quickgrove** only supports a handful of objective functions and most +notably does not have categorical support yet. In theory, categorical variables +make better candidates for pruning based on filter conditions. It only +supports XGBoost format. +- **Model Format**: XGBoost JSON is straightforward to parse. Other formats +(e.g. LightGBM, scikit-learn trees) require similar logic or conversion steps. +- **Edge Cases**: If the filter references columns not in the model features, +or if multiple filters combine in more complex ways, your rewriting logic may +need more robust parsing. +- **When to Use**: This approach is beneficial when queries often filter on the +same columns your trees split on. For purely adhoc queries or rarely used +filters, the overhead of rewriting might outweigh the benefit. + + +## Conclusion + +Combining **Ibis** with a prune-friendly framework like quickgrove lets you +optimize large-scale ML inference inside ML workflows. By **pushing filter +predicates down into your decision trees**, you speed up queries significantly. + +With LetSQL, you can streamline this entire process—especially if you’re +looking for an out-of-the-box solution that integrates with multiple engines +along with batteries included features like caching and aggregate/window UDFs. +For the next steps, consider experimenting with more complex models, exploring +different tree pruning strategies, or even extending this pattern to other ML +models beyond GBDTs. + +- **Try it out**: Explore the Ibis documentation to learn how to build custom +UDFs. +- **Dive deeper**: Check out [quickgrove](https://github.com/letsql/trusty) or +read the Raven optimizer [paper](https://arxiv.org/pdf/2206.00136). +- **Experiment with LetSQL**: If you need a polished solution for dynamic ML +UDF rewriting, [LetSQL](https://github.com/letsql/letsql) may be just the +ticket. + +--- + +## Resources + +- **Raven Paper**: [End-to-end Optimization of Machine Learning Prediction +Queries](https://arxiv.org/pdf/2206.00136) +- **Ibis + Torch**: [Ibis Project Blog +Post](https://ibis-project.org/posts/torch/) +- [Multi-Engine Data Stack with +Ibis](https://www.letsql.com/posts/multi-engine-data-stack-ibis/)