章节 01
导读 / 主楼:DuckDB-ML:在 SQL 中直接运行机器学习的 DuckDB 扩展
duckdb-ml 是一个 DuckDB 扩展,允许用户直接在 SQL 查询中训练、预测和评估机器学习模型。它提供了四个核心表函数:ml_fit、ml_predict、ml_evaluate 和 ml_explain,支持 PCA 等算法,并将模型版本存储在 SQLite 注册表中。
正文
duckdb-ml 是一个 DuckDB 扩展,允许用户直接在 SQL 查询中训练、预测和评估机器学习模型。它提供了四个核心表函数:ml_fit、ml_predict、ml_evaluate 和 ml_explain,支持 PCA 等算法,并将模型版本存储在 SQLite 注册表中。
章节 01
duckdb-ml 是一个 DuckDB 扩展,允许用户直接在 SQL 查询中训练、预测和评估机器学习模型。它提供了四个核心表函数:ml_fit、ml_predict、ml_evaluate 和 ml_explain,支持 PCA 等算法,并将模型版本存储在 SQLite 注册表中。
章节 02
ml_fit(model, options, transforms, table) 函数接受模型名称、配置选项、转换规则和训练数据,返回包含模型版本信息的单行结果:\n\n- model(模型名称,VARCHAR)\n- version(版本号,BIGINT)\n- timestamp(时间戳,VARCHAR)\n\n每次调用都会创建一个新的不可变版本,确保实验的可重现性。\n\n### ml_predict:推理预测\n\nml_predict(model, table[, version]) 函数使用指定模型对新数据进行预测。默认使用最新版本,也可以通过 version 参数指定特定版本(version=0 表示最新,version>0 表示具体版本)。\n\n### ml_evaluate:模型评估\n\nml_evaluate(model, table[, version]) 函数计算模型在测试数据上的性能指标,帮助开发者了解模型的泛化能力。\n\n### ml_explain:模型解释\n\nml_explain(model, table[, version]) 函数提供模型的可解释性输出,对于理解模型决策过程至关重要。\n\n## 使用示例\n\n以下示例展示了如何在 DuckDB 中完成一个完整的 PCA(主成分分析)工作流:\n\nsql\n-- 训练 PCA 模型\nSELECT *\nFROM ml_fit(\n 'pca_california',\n {'model_type':'pca', 'num_components':2, 'whiten':false},\n NULL,\n (SELECT * FROM california_train)\n);\n\n-- 使用最新版本进行预测\nSELECT * FROM ml_predict('pca_california', (SELECT * FROM california_test));\n\n-- 评估模型性能\nSELECT * FROM ml_evaluate('pca_california', (SELECT * FROM california_test));\n\n-- 使用特定版本进行预测\nSELECT * FROM ml_predict('pca_california', (SELECT * FROM california_test), version = 1);\n\n\n这种纯 SQL 的工作流消除了上下文切换的成本,数据分析师可以在熟悉的环境中完成 ML 任务。\n\n## 模型注册表与版本管理\n\nduckdb-ml 使用 SQLite 作为模型注册表,路径按以下优先级解析:\n\n1. PROJECT_DB_PATH 环境变量\n2. 操作系统默认路径:\n - Linux/macOS: ~/.duckdb-ml.db\n - Windows: %APPDATA%\\duckdb-ml\\duckdb-ml.db(回退到 %USERPROFILE%\\.duckdb-ml.db)\n\n模型条目存储在扩展拥有的 duckdb_ml_models 表中,这种设计确保了:\n\n- 版本隔离:每个训练调用创建新版本,不影响现有生产模型\n- 可重现性:可以精确回溯到任何历史版本\n- 原子性:模型切换是瞬时的,无需停机部署\n\n## 架构设计与技术考量\n\n该扩展基于 DuckDB 的 C++ 扩展框架构建,采用模板化设计以简化开发和分发。构建系统需要编译 DuckDB 核心和单元测试二进制文件,这带来了一定的构建时间开销。\n\n为优化开发体验,项目官方推荐使用 ccache 和 ninja:\n\nbash\n# 使用 ninja 和 ccache 加速构建\nGEN=ninja make\n\n\n这样可以确保 DuckDB 核心只需编译一次,后续扩展修改可以快速增量构建。\n\n## 安装与使用\n\n从 S3 安装自定义扩展需要两个步骤:\n\n1. 启用未签名扩展\n\nCLI 方式:\nbash\nduckdb -unsigned\n\n\nPython 方式:\npython\ncon = duckdb.connect(':memory:', config={'allow_unsigned_extensions': 'true'})\n\n\nNode.js 方式:\njavascript\ndb = new duckdb.Database(':memory:', {\"allow_unsigned_extensions\": \"true\"});\n\n\n2. 设置扩展仓库\n\nsql\nSET custom_extension_repository='bucket.s3.eu-west-1.amazonaws.com/<extension_name>/latest';\n\n\n3. 安装并加载\n\nsql\nINSTALL ml;\nLOAD ml;\n\n\n## 开发环境配置\n\n对于使用 CLion 的开发者,项目提供了详细的配置指南:\n\n1. 确保 DuckDB 子模块已初始化\n2. 打开 ./duckdb/CMakeLists.txt(而非顶层 CMakeLists.txt)作为项目\n3. 通过 Tools → CMake → Change Project Root 将项目根目录指向仓库根目录\n4. 在 CMake 设置中添加构建类型(Debug、Release、RelDebug 等)\n5. 在 CMake Options 中添加 -DDUCKDB_EXTENSION_CONFIGS=<path_to_extension_CMakeLists.txt>\n6. 配置 unittest 作为运行目标,添加 --test-dir ../../.. [sql] 参数以仅运行扩展特定测试\n\n## 测试策略\n\n项目采用 SQL 测试作为主要测试方式,测试文件位于 ./test/sql 目录。运行测试的命令为:\n\nbash\nmake test\n\n\n这种测试方式与 DuckDB 的测试框架保持一致,确保扩展与核心系统的兼容性。\n\n## 适用场景与价值\n\nduckdb-ml 特别适合以下场景:\n\n- 数据分析师:无需学习 Python 即可完成常见的 ML 任务\n- ETL 管道:在数据转换过程中嵌入 ML 推理\n- 边缘计算:轻量级部署,无需完整的 Python 环境\n- 原型验证:快速实验不同模型和参数\n\n通过将 ML 能力直接集成到数据库中,duckdb-ml 降低了机器学习的入门门槛,同时保持了生产环境所需的性能和可靠性。\n\n## 总结\n\nduckdb-ml 代表了数据库内机器学习(In-Database Machine Learning)的一个实践范例。它证明了在保持 SQL 声明式风格的同时,完全可以实现复杂的 ML 工作流。对于已经使用 DuckDB 进行数据分析的团队来说,这个扩展提供了一种自然的能力扩展路径,无需引入额外的技术栈。章节 03
DuckDB-ML:在 SQL 中直接运行机器学习的 DuckDB 扩展\n\n项目概述\n\nduckdb-ml 是一个为 DuckDB 数据库设计的机器学习扩展,它将传统上需要 Python 或 R 等外部工具完成的 ML 工作流,直接集成到 SQL 查询中。这种设计理念体现了"数据在哪里,计算就在哪里"的思想,避免了数据在数据库和 ML 框架之间来回传输的开销。\n\n该扩展基于 DuckDB 的官方扩展模板构建,提供了四个核心表函数,覆盖了机器学习生命周期的主要环节:训练、预测、评估和解释。所有模型版本都存储在一个 SQLite 注册表中,支持版本管理和回溯。\n\n核心功能:四个表函数\n\nduckdb-ml 通过 SQL 表函数暴露 ML 能力,这种设计保持了 DuckDB 的声明式风格:\n\nml_fit:模型训练\n\nml_fit(model, options, transforms, table) 函数接受模型名称、配置选项、转换规则和训练数据,返回包含模型版本信息的单行结果:\n\n- model(模型名称,VARCHAR)\n- version(版本号,BIGINT)\n- timestamp(时间戳,VARCHAR)\n\n每次调用都会创建一个新的不可变版本,确保实验的可重现性。\n\nml_predict:推理预测\n\nml_predict(model, table[, version]) 函数使用指定模型对新数据进行预测。默认使用最新版本,也可以通过 version 参数指定特定版本(version=0 表示最新,version>0 表示具体版本)。\n\nml_evaluate:模型评估\n\nml_evaluate(model, table[, version]) 函数计算模型在测试数据上的性能指标,帮助开发者了解模型的泛化能力。\n\nml_explain:模型解释\n\nml_explain(model, table[, version]) 函数提供模型的可解释性输出,对于理解模型决策过程至关重要。\n\n使用示例\n\n以下示例展示了如何在 DuckDB 中完成一个完整的 PCA(主成分分析)工作流:\n\nsql\n-- 训练 PCA 模型\nSELECT *\nFROM ml_fit(\n 'pca_california',\n {'model_type':'pca', 'num_components':2, 'whiten':false},\n NULL,\n (SELECT * FROM california_train)\n);\n\n-- 使用最新版本进行预测\nSELECT * FROM ml_predict('pca_california', (SELECT * FROM california_test));\n\n-- 评估模型性能\nSELECT * FROM ml_evaluate('pca_california', (SELECT * FROM california_test));\n\n-- 使用特定版本进行预测\nSELECT * FROM ml_predict('pca_california', (SELECT * FROM california_test), version = 1);\n\n\n这种纯 SQL 的工作流消除了上下文切换的成本,数据分析师可以在熟悉的环境中完成 ML 任务。\n\n模型注册表与版本管理\n\nduckdb-ml 使用 SQLite 作为模型注册表,路径按以下优先级解析:\n\n1. PROJECT_DB_PATH 环境变量\n2. 操作系统默认路径:\n - Linux/macOS: ~/.duckdb-ml.db\n - Windows: %APPDATA%\\duckdb-ml\\duckdb-ml.db(回退到 %USERPROFILE%\\.duckdb-ml.db)\n\n模型条目存储在扩展拥有的 duckdb_ml_models 表中,这种设计确保了:\n\n- 版本隔离:每个训练调用创建新版本,不影响现有生产模型\n- 可重现性:可以精确回溯到任何历史版本\n- 原子性:模型切换是瞬时的,无需停机部署\n\n架构设计与技术考量\n\n该扩展基于 DuckDB 的 C++ 扩展框架构建,采用模板化设计以简化开发和分发。构建系统需要编译 DuckDB 核心和单元测试二进制文件,这带来了一定的构建时间开销。\n\n为优化开发体验,项目官方推荐使用 ccache 和 ninja:\n\nbash\n使用 ninja 和 ccache 加速构建\nGEN=ninja make\n\n\n这样可以确保 DuckDB 核心只需编译一次,后续扩展修改可以快速增量构建。\n\n安装与使用\n\n从 S3 安装自定义扩展需要两个步骤:\n\n1. 启用未签名扩展\n\nCLI 方式:\nbash\nduckdb -unsigned\n\n\nPython 方式:\npython\ncon = duckdb.connect(':memory:', config={'allow_unsigned_extensions': 'true'})\n\n\nNode.js 方式:\njavascript\ndb = new duckdb.Database(':memory:', {\"allow_unsigned_extensions\": \"true\"});\n\n\n2. 设置扩展仓库\n\nsql\nSET custom_extension_repository='bucket.s3.eu-west-1.amazonaws.com/<extension_name>/latest';\n\n\n3. 安装并加载\n\nsql\nINSTALL ml;\nLOAD ml;\n\n\n开发环境配置\n\n对于使用 CLion 的开发者,项目提供了详细的配置指南:\n\n1. 确保 DuckDB 子模块已初始化\n2. 打开 ./duckdb/CMakeLists.txt(而非顶层 CMakeLists.txt)作为项目\n3. 通过 Tools → CMake → Change Project Root 将项目根目录指向仓库根目录\n4. 在 CMake 设置中添加构建类型(Debug、Release、RelDebug 等)\n5. 在 CMake Options 中添加 -DDUCKDB_EXTENSION_CONFIGS=<path_to_extension_CMakeLists.txt>\n6. 配置 unittest 作为运行目标,添加 --test-dir ../../.. [sql] 参数以仅运行扩展特定测试\n\n测试策略\n\n项目采用 SQL 测试作为主要测试方式,测试文件位于 ./test/sql 目录。运行测试的命令为:\n\nbash\nmake test\n\n\n这种测试方式与 DuckDB 的测试框架保持一致,确保扩展与核心系统的兼容性。\n\n适用场景与价值\n\nduckdb-ml 特别适合以下场景:\n\n- 数据分析师:无需学习 Python 即可完成常见的 ML 任务\n- ETL 管道:在数据转换过程中嵌入 ML 推理\n- 边缘计算:轻量级部署,无需完整的 Python 环境\n- 原型验证:快速实验不同模型和参数\n\n通过将 ML 能力直接集成到数据库中,duckdb-ml 降低了机器学习的入门门槛,同时保持了生产环境所需的性能和可靠性。\n\n总结\n\nduckdb-ml 代表了数据库内机器学习(In-Database Machine Learning)的一个实践范例。它证明了在保持 SQL 声明式风格的同时,完全可以实现复杂的 ML 工作流。对于已经使用 DuckDB 进行数据分析的团队来说,这个扩展提供了一种自然的能力扩展路径,无需引入额外的技术栈。