DuckDB 想做机器学习——5 个扩展,半个 PostgresML
你用 DuckDB 跑完分析,想顺手训个 XGBoost 预测下个月的销量。
直觉做法:SELECT * FROM sales → 导出 CSV → Python 里 import xgboost → 训练 → 预测 → 导回 DuckDB。
来回倒数据,四步走。有没有更简单的?
PostgreSQL 用户会说:装个 PostgresML,SELECT pgml.train('xgboost', ...) 就搞定,一条 SQL 训练 + 推理。
那 DuckDB 呢?我把社区 8 个 ML 相关扩展翻了一遍。结论:能做一点,但离"数据库内 ML"还差一口气。
● ● ●
现有哪些扩展?
先上总表:
| 扩展 | 能训练吗 | 能推理吗 | 核心能力 | 成熟度 |
|---|---|---|---|---|
| mlpack | ✅ 5 种算法 | ✅ | AdaBoost / Random Forest / 线性回归 | 🧪 MVP 实验 |
| infera | ❌ | ✅ ONNX | 加载 ONNX 模型在 SQL 里推理 | 🧪 v0.2.0 |
| anofox_statistics | ✅ 9 种回归 | ✅ | OLS/Ridge/ElasticNet/Poisson 等 | 🟡 活跃开发 |
| flockmtl | ❌ | ✅ 外部 API | LLM 文本生成、嵌入、RAG | 🧪 学术研究 |
| whisper | ❌ | ✅ | 语音转文字 | 🟡 稳定 |
| pic2vec | ❌ | ✅ | 图像→向量嵌入 | 🧪 实验 |
mlpack——唯一的训练+推理一体化方案
维护者是 Dirk Eddelbuettel,R 社区的老炮(Rcpp 的作者)。他把 mlpack C++ 库包成了 DuckDB 扩展。
用法是表驱动 API:四张表——特征表 X、标签表 Y、参数表 Z、模型表 M:
-- 训练
CREATE TEMP TABLE result AS
SELECT * FROM mlpack_random_forest_train("X", "Y", "Z", "M");
-- 预测
SELECT * FROM mlpack_random_forest_pred("new_data", "M");
模型序列化成 JSON 存在表里,用完可以持久化。
五个算法:AdaBoost、Random Forest、线性回归、逻辑回归、KMeans。
问题是它明确标着"experimental MVP demo",API 随时可能变,而且只有五个算法——没有 XGBoost,没有 LightGBM,只有最基础的。
infera——ONNX 推理,干净好用但只管推理
Rust 写的,Tract ONNX 引擎。把 .onnx 模型文件加载进来,直接 SELECT infera_predict('my_model', col1, col2) 就出结果。
SELECT infera_load_model('linear', 'https://.../linear.onnx');
SELECT infera_predict('linear', 1.0, 2.0, 3.0);
-- 1.75
支持远程模型、本地模型、批量推理、多输出。API 设计得干净利落。
但它是纯推理引擎——模型必须在外部训好(Python 用 sklearn/ PyTorch 训完导出 ONNX),然后拿进 DuckDB 跑推理。训练这半段还是得回到 Python。
anofox_statistics——统计推断最强,但许可卡脖子
这是 DuckDB ML 生态里最像"生产级"的东西。
9 种回归方法(OLS、Ridge、Elastic Net、WLS、Poisson GLM、ALM 等),30+ 假设检验(t-test、ANOVA、卡方、Shapiro-Wilk……),全部内置。而且支持 GROUP BY——一条 SQL 按地区分别建模,这是 DuckDB 列式引擎的天然优势:
SELECT region, ols_fit_agg(sales, [price], MAP{'intercept': true}) AS model
FROM sales_data
GROUP BY region;
数值精度拿 R 的 lm() 和 glmnet 交叉验证过,这一点很靠谱。
但它是 BSL 1.1 许可——免费用于内部研发,商用需要许可证。而且只有回归,没有分类、没有聚类、没有降维。
flockmtl——LLM 桥接,但全靠外部 API
它把 LLM 调用做成了 SQL 一等公民:
CREATE PROMPT('summarize', '用一句话概括:{{text}}');
CREATE MODEL('gpt4', 'gpt-4o', 'openai');
SELECT llm_complete({'model_name': 'gpt4'}, {'prompt_name': 'summarize', ...});
Prompt 管理和模型注册的设计很好。但它纯靠调用外部 API——OpenAI、Anthropic 之类的云端模型。没有本地 LLM 托管,没有离线推理。
● ● ●
对标:PostgresML 做了什么?
PostgresML 是一个 PostgreSQL 扩展,把整个 ML 管线塞进了数据库:
pgml.train()——47+ 算法,从 XGBoost 到神经网络pgml.predict()——训练好的模型直接 SQL 调用pgml.transform()——本地跑 HuggingFace 模型做文本生成、翻译pgml.embed()/pgml.chunk()/pgml.rank()——完整的 RAG 管线- GPU 加速——CUDA 直接跑
一句话:训练和推理都在库里,不需要 Python,不需要导出数据。
DuckDB 能做到什么程度?
| 能力 | PostgresML | DuckDB 现有 |
|---|---|---|
| 训练 | ✅ 47+ 算法统一 API | mlpack 5 种 + anofox 9 种回归,两套 API |
| 推理 | ✅ | ✅ infera ONNX + mlpack |
| GPU | ✅ CUDA | ❌ 零 |
| XGBoost | ✅ | ❌ |
| 本地 LLM | ✅ HuggingFace | ❌ flockmtl 只调 API |
| RAG 管线 | ✅ chunk/embed/rank/transform | ❌ 碎片化 |
| 统计推断 | 基础 | ✅ anofox 29 种检验 |
● ● ●
差在哪?
三个致命缺口:
1. 没有统一 API。 要训练用 mlpack,要 ONNX 推理用 infera,要统计检验用 anofox,要 LLM 用 flockmtl。每个扩展一套语法,没有 CREATE MODEL / PREDICT 这样的统一入口。
2. 没有 XGBoost。 这是工业界最常用的算法——Kaggle 竞赛 80% 的冠军方案都有它。DuckDB 社区没人做,也没有 GPU 加速。
3. 训练能力太弱。 mlpack 只有 5 个算法,anofox 只有回归。加起来还不如一个 scikit-learn 的基础功能集。
● ● ●
我打算做个 duckdb_ml
我的判断是:DuckDB ML 生态不缺"连接外部工具的桥"——flockmtl 连 LLM API、infera 连 ONNX 模型,桥已经不少了。
缺的是一个原生训练引擎——轻量、列式原生、训练+推理一体。
所以我在认真考虑做一个 DuckDB ML 扩展。底线功能:
- 统一 SQL API:
CREATE MODEL/PREDICT/LIST MODELS/DROP MODEL - XGBoost + LightGBM 推理(ONNX 格式,训练在 Python 侧完成,导出后加载进 DuckDB)
- 线性模型原生训练(利用 DuckDB 列式引擎,不依赖外部库)
- 模型持久化到 DuckDB 内部存储
不做的事:不碰 GPU(保持轻量)、不碰深度学习(交给 infera)、不碰 LLM(交给 flockmtl)。
在 Python 里快速训个模型 → 导出 ONNX → DuckDB 里加载 → SELECT PREDICT(...) ——这是我想要的体验。
调研详细数据、每个扩展的 GitHub 链接、和 PostgresML 的逐项对比,都记在 wiki 里了。
- mlpack: duckdb.org/community_extensions/extensions/mlpack
- infera: github.com/CogitatorTech/infera
- anofox_statistics: github.com/DataZooDE/anofox-statistics
- flockmtl: duckdb.org/community_extensions/extensions/flockmtl
- PostgresML: github.com/postgresml/postgresml
- DuckDB 扩展分析: mjboothaus.github.io/duckdb-extensions-analysis/