Daft 向量距离扩展 dvector 实战指南:基于原生 Rust 扩展实现 L2、余弦、汉明等向量距离函数 📅 发布时间:2026/9/17 12:39:34 👁 浏览次数: Daft 向量距离扩展 dvector 实战指南基于原生 Rust 扩展实现 L2、余弦、汉明等向量距离函数【免费下载链接】DaftHigh-performance data engine for AI and multimodal workloads. Process images, audio, video, and structured data at any scale项目地址: https://gitcode.com/GitHub_Trending/da/Daftdvector 是 Daft 官方示例仓库中提供的一个原生扩展native extension它以 Rust 动态库cdylib的形式为 Daft 数据引擎补充了 6 个向量距离标量函数可直接嵌入 Daft 表达式 DSL 对向量列做逐行距离计算。读完本文你将掌握 dvector 全部函数的数学定义与边界行为、向量列的数据类型约束、安装与加载方式以及从 Python 包装层examples/dvector/dvector/init.py到 Rust 内核examples/dvector/src/lib.rs、examples/dvector/src/vectors.rs的完整实现原理。dvector 是什么为 Daft 定制的向量距离函数扩展Daft 原生扩展基于 Arrow C Data Interface 这一稳定的 C ABI 构建扩展与 Daft 内部的 arrow-rs 版本解耦任何遵守该 ABI 的 Rust 扩展都能被 Daft 运行时通过dlopen加载参见 docs/extensions/authoring.md。dvector 正是这条扩展路径的一个完整落地示例它把一组向量相似度/距离计算下沉到 Rust 侧通过会话Session注册为 Daft 函数从而在 Daft DataFrame 中直接以表达式的方式调用全程无逐行 Python 开销。dvector 提供的全部函数如下与 examples/dvector/README.md 的函数表一致函数描述输入类型输出类型l2_distance(a, b)欧几里得距离L2float 向量Float64inner_product(a, b)负内积遵循 pgvector 约定float 向量Float64cosine_distance(a, b)余弦距离零模向量返回 nullfloat 向量Float64l1_distance(a, b)曼哈顿距离L1float 向量Float64hamming_distance(a, b)不同位置计数boolean 向量UInt32jaccard_distance(a, b)1 - 交集/并集并集为空时返回 nullboolean 向量Float64向量列支持FixedSizeList、List或LargeList三种布局浮点向量元素支持Float32与Float64两种精度布尔向量元素则为Boolean。向量数据类型的完整约束三种列表布局dvector 的两个输入参数必须是向量列向量既可以是定长的FixedSizeList也可以是变长的Listi32 offset或LargeListi64 offset。在 src/vectors.rs 中三种布局被统一抽象为VectorLayout枚举Fixed(i32)定长列表每个向量占用固定元素个数Variable32(OffsetBufferi32)List的偏移缓冲Variable64(OffsetBufferi64)LargeList的偏移缓冲。元素精度与统一视图浮点向量元素支持Float32和Float64。从源码 src/vectors.rs 可以看到extract_float_values对Float64元素直接借用底层切片零拷贝对Float32元素则逐元素提升为f64后持有为Vecf64任何其他元素类型都会返回TypeError“unsupported element type ... expected Float32 or Float64”。因此所有浮点距离函数内部统一以f64计算。布尔向量汉明、杰卡德距离要求元素类型严格为Boolean否则同样抛出TypeErrorsrc/vectors.rs。空值null语义向量列本身允许包含 null 行只要任意一侧的向量为 null对应输出行即为 null见 src/vectors.rs 的空值检查与 tests/test_dvector.py 的test_l2_with_null用例。此外cosine_distance在任一向量模为零分母为 0时返回 null而不是报错或返回 NaNsrc/lib.rsjaccard_distance在并集为空两个向量所有位均为 false时返回 nullsrc/lib.rs。维度校验同一行内两个向量维度不一致会触发运行时错误dimension mismatch at row {row}: {a_len} vs {b_len}src/vectors.rs。换言之dvector 要求逐行配对的两个向量长度必须相同但不同行之间的维度可以不同例如变长列表列。安装与构建dvector 是源码级示例扩展安装前需要准备Rust 工具链cargo / rustc因为需要把 Cargo.toml 中声明的 Rust crate 编译为cdylibPython 3.10以及setuptools-rust构建后端。构建配置的关键点在 setup.py 与 pyproject.tomlpyproject.toml声明setuptoolssetuptools-rust作为构建系统项目依赖daft并通过[tool.uv.sources]把 daft 指向仓库根目录path ../.., editable truesetup.py通过RustExtension(dvector.libdvector, ...)将编译产物.so放到 Python 包dvector/目录内Binding.NoBinding因为扩展导出的是原始 C 符号而非 PyO3 绑定stripTrue压缩体积Cargo.toml 中[lib]的crate-type [cdylib]保证生成可被dlopen加载的动态库并依赖daft-ext启用arrow-57特性与仓库使用的 arrow-rs 57 系列版本匹配。开发模式下推荐用 uv 以可编辑方式安装并运行测试# 编译 Rust cdylib 并以可编辑模式安装含原生库 uv pip install -e . # 运行测试 pytest -v tests/快速上手在 Daft DataFrame 中使用 dvector加载扩展安装完成后dvector 的函数并不会自动生效需要显式加载到当前会话。Daft 的Session.load_extension接受模块、模块路径或共享库文件路径实现见 daft/session.py并且在进程内只会dlopen一次函数仅在加载了该扩展的会话中可用详见 docs/extensions/authoring.md 的 Session isolation 说明以及 tests/test_dvector.py 中“未加载扩展即调用会报not found”的验证用例。import daft import dvector from dvector import l2_distance # 将扩展加载进当前活动会话 daft.load_extension(dvector)计算 L2 距离构造两个浮点向量列并直接以表达式调用l2_distance示例取自 examples/dvector/README.mddf daft.from_pydict({ a: [[1.0, 2.0, 3.0], [0.0, 0.0, 0.0]], b: [[4.0, 5.0, 6.0], [1.0, 1.0, 1.0]], }) df.select(l2_distance(daft.col(a), daft.col(b))).collect() # ╭───────────╮ # │ result │ # │ --- │ # │ Float64 │ # ╞═══════════╡ # │ 5.196152 │ # ├╌╌╌╌╌╌╌╌╌╌╌┤ # │ 1.732051 │ # ╰───────────╯第一行sqrt((1-4)^2 (2-5)^2 (3-6)^2) sqrt(27) ≈ 5.196152第二行sqrt(000) 0与[1,1,1]的距离为sqrt(3) ≈ 1.732051与输出完全吻合。Python 包装层如何映射到 Rust 函数dvector/init.py 中每个函数都是一行薄包装通过daft.get_function(dvector_l2_distance, a, b)之类的调用按名称在当前会话中解析已注册的扩展函数get_function的实现见 daft/session.py 附近。函数名统一采用dvector_fn前缀避免与其他扩展冲突这是 docs/extensions/authoring.md 推荐的命名规范。因此你既可以直接使用这些 Python 包装函数带类型标注与文档字符串也可以理解它们的本质是名称到会话内注册函数的解析。源码级原理六个距离函数的内核实现扩展注册入口src/lib.rs 定义了扩展模块#[daft_extension]宏为共享库生成 Daft 运行时查找的 C 符号daft_module_magicimpl DaftExtension for DvectorExtension在install(session)钩子中通过session.define_function依次注册六个函数每个函数是一个独立结构体由#[daft_func_batch(return_dtype ...)]宏声明输出类型接收ArrayRefArrow 数组并返回DaftResultArrayRef数据全程以 Arrow 数组批量流动无逐行 Python 解释开销。浮点距离L2 / 内积 / 余弦 / L1四个浮点函数共用 src/vectors.rs 中的统一向量列视图FloatVectorColumn与三种批量映射器map_float_vectors、map_float_vectors_nullable、map_bool_vectors_*核心逻辑如下src/lib.rsdvector_l2_distancesqrt(sum((x-y)^2))dvector_inner_product-(sum(x*y))即负内积。这是 pgvector 的排序约定——距离越小表示内积越大便于按“相似度优先”做升序 top-K测试用例 tests/test_dvector.py 验证了1*42*53*6 32取负后输出-32.0dvector_cosine_distance一次遍历同时累加点积与两向量各自平方和计算1 - dot/(|a|*|b|)当分母为 0零模向量时返回None即输出 nullsrc/lib.rsdvector_l1_distancesum(|x-y|)。布尔距离汉明 / 杰卡德两个布尔函数通过BoolVectorColumn统一视图读取布尔向量每行切片为一个BooleanArray逻辑为src/lib.rsdvector_hamming_distancefilter(|x, y| x ! y).count()输出 UInt32dvector_jaccard_distance先统计并集任一为 true并集为 0 时返回 null否则统计交集两者均为 true输出1 - inter/union。测试用例 tests/test_dvector.py 验证了[T,T,F,F]与[T,F,T,F]的输出为1 - 1/3 2/3以及全 false 向量输出 null。批量映射与性能设计src/vectors.rs 中的映射器在实现上做足了向量化基础工作按列长度预分配Float64Builder/UInt32Builder容量、借用底层f64切片避免拷贝F64Values::Borrowed、行级 null 传播、维度校验前置。这意味着距离计算完全发生在 Rust 的 Arrow 数组层天然适合 Daft 的列式执行模型——这是该扩展能够在批量 embedding 相似度打分等场景直接嵌入查询管道的原因。测试与质量保障dvector 的测试覆盖tests/test_dvector.py是一个值得参照的扩展验证模板会话隔离sessfixture 创建独立Session并load_extension(dvector)测试通过with sess:上下文管理器限定查询会话数值正确性对 L2、内积、余弦、L1、汉明、杰卡德逐一断言精确数学值如sqrt(2)、-32.0、1 - 1/sqrt(2)、2/3边界行为null 行传播为 null、零模向量余弦为 null、全 false 杰卡德为 null、未加载扩展时调用报错。运行pytest -v tests/即可在本地复现全部用例。典型应用场景基于以上能力dvector 适合在 Daft 管道中直接完成以下工作向量检索/相似度排序对 embedding 列两两计算 L2 或余弦距离配合 Daft 的sort/limit做 top-K 近似最近邻筛选内积遵循 pgvector 约定便于复用排序语义多模态/批量打分对图像、文本等模态产出的浮点向量批量计算距离矩阵或逐行打分集合类相似度对布尔向量如标签集合的 one-hot/多热编码使用汉明或杰卡德距离例如文档去重、样本相似度筛查。总结dvector 是理解 Daft 原生扩展机制的极佳范例它以 6 个标量函数覆盖了浮点与布尔向量两类距离计算兼容三种列表布局与两种浮点精度并完整实现了 null 传播、维度校验等边界语义。无论是直接把它作为向量距离函数库使用还是对照 docs/extensions/authoring.md 将它作为编写自有 Rust 扩展的蓝本你都可以从本仓库的 examples/dvector/ 目录中获得开箱即用的参考实现。【免费下载链接】DaftHigh-performance data engine for AI and multimodal workloads. Process images, audio, video, and structured data at any scale项目地址: https://gitcode.com/GitHub_Trending/da/Daft创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考