拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Lance Rust 实现指南:从数据集写入、随机访问到向量索引

Lance Rust 实现指南从数据集写入、随机访问到向量索引【免费下载链接】lanceOpen Lakehouse Format for Multimodal AI. Convert from Parquet in 2 lines of code for 100x faster random access, vector index, and data versioning. Compatible with Pandas, DuckDB, Polars, Pyarrow, and PyTorch with more integrations coming..项目地址: https://gitcode.com/GitHub_Trending/la/lanceLance 是一个面向多模态 AI 的开源湖仓Lakehouse格式本指南围绕仓库中 Rust 核心 craterust/lance展开系统讲解如何用 Rust API 完成数据集创建、流式读取、按行随机访问Take以及向量索引构建与查询。读完本文你将掌握Dataset::write、Dataset::open、Dataset::take、Dataset::create_index等核心接口的完整用法并能结合源码理解其底层工作方式。安装在rust/lance/Cargo.toml中lancecrate 的name为lance版本号与工作区一致version.workspace true并声明readme README.md。使用 Rust 生态有两种安装方式方式一通过 Cargo 全局安装cargo install lance安装完成后会得到仓库提供的 CLI 工具lq由[[bin]] name lq定义见 rust/lance/Cargo.toml该二进制要求启用clifeature。方式二作为项目依赖引入在Cargo.toml中添加[dependencies] lance { git https://gitcode.com/GitHub_Trending/la/lance }lancecrate 默认启用一组对象存储后端 featureaws、azure、gcp、oss、huggingface、tencent、tos、goosefs、geo见 rust/lance/Cargo.toml对应lance-io中对 AWS S3、Azure Blob、GCP、阿里云 OSS、Hugging Face、腾讯云、火山引擎 TOS、GooseFS 等存储的适配。若你只使用本地磁盘可以关闭默认 feature 以缩短编译时间如需lqCLI 或 DynamoDB 提交处理器可分别启用cli或dynamodbfeature。从依赖结构看lancecrate 是一个面向用户的聚合层内部组合了lance-arrow、lance-core、lance-encoding、lance-file、lance-index、lance-io、lance-linalg、lance-table、lance-tokenizer等子 crate见 rust/lance/Cargo.toml文档与示例中的Dataset、Scanner、VectorIndexParams均由该聚合 crate 统一对外导出。创建数据集写入Lance 的写入入口是Dataset::write。在 rust/lance/src/dataset.rs 中其签名为pub async fn write( batches: impl RecordBatchReader Send static, dest: impl IntoWriteDestination_, params: OptionWriteParams, ) - ResultSelf假设batches是一个 ArrowVecRecordBatchschema是 ArrowSchemaRef最简单的写入如下取自原文档示例use lance::{dataset::WriteParams, Dataset}; let write_params WriteParams::default(); let mut reader RecordBatchIterator::new( batches.into_iter().map(Ok), schema ); Dataset::write(reader, uri, Some(write_params)).await.unwrap();注意RecordBatchIterator::new需要use arrow::record_batch::RecordBatchIterator;显式引入完整可运行版本可参考仓库示例 rust/examples/src/write_read_ds.rs。WriteParams 核心参数WriteParams定义在 rust/lance/src/dataset/write.rs原文档中通过WriteParams::default()使用默认值。要写出符合生产需求的配置需要了解以下关键字段及其默认值来自impl Default见 rust/lance/src/dataset/write.rs字段默认值说明max_rows_per_file1,048,576约 100 万行每个数据文件的最大行数max_rows_per_group1024每个 row group 的最大行数max_bytes_per_file90 GiB文件大小的软上限对象存储普遍有 100 GB 硬限制故默认留有余量modeWriteMode::Create写入模式见下文store_paramsNone对象存储参数如自定义 ObjectStoredata_storage_versionNone数据文件格式版本对已存在的数据集省略时沿用 manifest 中的默认版本新建数据集则使用最新稳定版本enable_stable_row_idsfalse是否启用稳定行 ID使 compaction 后无需重建二级索引enable_v2_manifest_pathstrue新数据集是否使用 v2 manifest 路径支持对象存储上的常量时间最新 manifest 查找源码对max_bytes_per_file给出了精确的行为说明这是一个软限制实际文件可能略大检测到超限后仍需刷写 footer且该限制在每组写入后检查因此当max_rows_per_group很大时超限幅度可能变大——在 rust/lance/src/dataset/write.rs 中有详细注释。WriteModeCreate / Append / OverwriteWriteMode定义在 rust/lance/src/dataset/write.rs共三种取值Create创建全新数据集若已存在则报错Append向已有数据集追加Overwrite覆盖为一个新版本数据集不存在时等价于创建。仓库示例 rust/examples/src/write_read_ds.rs 演示了用Overwrite模式反复写入同一路径的用法let write_params WriteParams { mode: WriteMode::Overwrite, ..Default::default() }; Dataset::write(batches, data_path, Some(write_params)).await?;写入本质上是版本提交每次write都会生成新版本 manifest并通过commit_handler默认根据对象存储能力选择 Rename 提交或 S3 风格的提交方式原子提交从而保证 ACID 语义。读取数据集扫描读取的入口是Dataset::open见 rust/lance/src/dataset.rs随后通过scan()创建Scanner见 rust/lance/src/dataset.rs。原文档示例let dataset Dataset::open(path).await.unwrap(); let mut scanner dataset.scan(); let batches: VecRecordBatch scanner .try_into_stream() .await .unwrap() .map(|b| b.unwrap()) .collect::VecRecordBatch() .await;Scanner定义在 rust/lance/src/dataset/scanner.rs是 Lance 查询的核心对象支持链式构建查询计划。仓库示例 rust/examples/src/ivf_hnsw.rs 展示了更丰富的 Scanner 用法let plan scan .project(columns) .unwrap() .with_row_id() .nearest(column, q, args.k) .unwrap() .minimum_nprobes(args.nprobe); println!({:?}, plan.explain_plan(true).await.unwrap());即project投影列 →with_row_id附带行 ID →nearest执行向量近邻查询 →minimum_nprobes设置 IVF 探测数最后try_into_stream()将执行计划物化为RecordBatch流。Scanner底层通过 DataFusion 构建物理执行计划源码中大量引用了datafusion_physical_plan因此向量检索、标量过滤与 SQL 聚合可以共用一个查询引擎这正是 Lance混合检索能力的基础。按行随机访问Take当只需要读取少量特定行时全表扫描是不划算的Lance 提供take直接按行号取数。原文档示例let values: ResultRecordBatch dataset.take([200, 199, 39, 40, 100], projection).await;take接受一个行索引数组和一个投影projection返回对应的RecordBatch行的顺序与输入索引一致。从底层实现看take会先把输入索引经删除向量deletion vector重映射为实际行地址再调用 fragment 级别的take见 rust/lance/src/dataset/fragment.rs最终由文件读取器按需加载对应的行组与页面。由于 Lance 数据文件按列行组组织并维护页面级索引随机访问只需要读取目标行所在的少量页面而不必解压整个文件——这也是 Lance 面向随机访问比 Parquet/Iceberg 快约 100 倍官方 README 声明这一设计目标的实现基础。实际使用中projection通常用ProjectionRequest构造例如 rust/examples/src/ivf_hnsw.rs 中的ProjectionRequest::from_columns([column], dataset.schema())。构建向量索引Lance 的核心能力之一是对向量列构建 ANN 索引。原文档示例假设embeddings是一个FixedSizeListArrayf32use ::lance::index::vector::VectorIndexParams; let params VectorIndexParams::default(); params.num_partitions 256; params.num_sub_vectors 16; // this will Err if list_size(embeddings) / num_sub_vectors does not meet simd alignment dataset.create_index([embeddings], IndexType::Vector, None, params, true).await;这里需要注意 API 演进原文档中直接为num_partitions/num_sub_vectors字段赋值的写法对应旧版 API在当前仓库源码中VectorIndexParams定义于 rust/lance/src/index/vector.rs已改为由stages: VecStageParams描述多阶段索引如 IVF → PQ / RQ / HNSW推荐使用语义化构造方法use lance::index::vector::VectorIndexParams; use lance_linalg::distance::MetricType; // IVF_PQ 索引256 个分区每个子向量 8 bit 量化 let params VectorIndexParams::ivf_pq( 256, // num_partitionsIVF 聚类数 8, // num_bitsPQ 每个子向量的量化位数当前仅支持 8 16, // num_sub_vectors子向量数量 MetricType::Cosine, // 距离度量L2 或 Cosine 50, // max_iterationsk-means 最大迭代次数 );VectorIndexParams在 rust/lance/src/index/vector.rs 中还提供了以下构造方式ivf_flat(num_partitions, metric_type)纯 IVF 索引不做量化适合小规模数据with_ivf_pq_params(metric_type, ivf, pq)分别指定IvfBuildParams与PQBuildParamsivf_rq(num_partitions, num_bits, distance_type)/ivf_rq_with_rotation(...)IVF 残差量化RQ索引with_ivf_hnsw_sq_params(metric_type, ivf, hnsw, sq)IVF HNSW 标量量化SQ的组合索引召回与延迟均衡较好仓库示例 rust/examples/src/ivf_hnsw.rs 给出了完整参数配置let mut ivf_params IvfBuildParams::new(128); ivf_params.sample_rate 20480; // 训练采样率 let hnsw_params HnswBuildParams::default() .ef_construction(100) // 建图时的搜索宽度 .num_edges(15); // 每个节点的最大出边数 let sq_params SQBuildParams::default(); let params VectorIndexParams::with_ivf_hnsw_sq_params( metric_type, ivf_params, hnsw_params, sq_params, );create_index 调用链create_index定义于DatasetIndexExttrait见 rust/lance/src/index.rsasync fn create_index( mut self, columns: [str], index_type: IndexType, name: OptionString, params: dyn IndexParams, replace: bool, ) - ResultIndexMetadata其内部会构造CreateIndexBuilder最终以Operation::CreateIndex事务提交索引建立过程见 rust/lance/src/index.rs返回IndexMetadata。示例中最后一个参数true表示允许替换同名已有索引。原文档特别提示当list_size(embeddings)不能被num_sub_vectors整除、不满足 SIMD 对齐要求时create_index会返回错误——这是构建 PQ 类索引时必须注意的前提条件通常要求向量维度能被子向量数整除。索引构建完成后即可通过Scanner::nearest执行 ANN 查询见上文读取数据集中的示例配合minimum_nprobes控制查询精度与延迟的取舍。Lance 是什么面向多模态 AI 的开放湖仓格式按 rust/lance/README.md 的定位Lance 是一个面向多模态 AI 的开放湖仓格式由文件格式file format、表格式table format与目录规范catalog spec三层构成可在对象存储之上搭建完整的 AI 数据湖仓。其关键特性包括表达力强的混合检索在同一数据集上同时支持向量相似度检索、全文检索BM25与 SQL 分析并配以加速的二级索引闪电般的随机访问官方 README 声明随机访问速度约为 Parquet / Iceberg 的 100 倍同时不牺牲扫描性能原生多模态数据支持可在同一格式中存放图片、视频、音频、文本与 embedding借助高效的 blob 编码与惰性加载lazy loading控制 IO数据演进Data Evolution无需整表重写即可高效新增列并回填默认值适配机器学习特征工程场景零拷贝版本管理内置 ACID 事务、时间旅行与自动版本管理无需额外基础设施丰富的生态集成支持 Apache Arrow、Pandas、Polars、DuckDB、Apache Spark、Ray、Trino、Apache Flink以及 Apache Polaris、Unity Catalog、Apache Gravitino 等开放目录。格式的底层协议定义在本仓库的 protos 目录file.proto、table.proto、index.proto、transaction.proto等Rust 实现侧的 proto 副本位于 rust/lance/protos。若想了解文件格式与表格式的更多规范细节可进一步阅读仓库文档 docs/format/index.md。继续深入仓库中的示例与测试如果你希望从会用进阶到看懂实现以下是仓库中值得继续阅读的入口完整可运行示例rust/examples/src/write_read_ds.rs写入 读取全流程、rust/examples/src/ivf_hnsw.rs向量索引构建 近邻查询 延迟基准、rust/examples/src/hnsw.rsHNSW 召回基准数据集实现rust/lance/src/dataset.rsopen/write/scan/take等入口、rust/lance/src/dataset/write.rsWriteParams、WriteMode扫描器实现rust/lance/src/dataset/scanner.rsScanner的查询计划构建索引实现rust/lance/src/index.rscreate_index事务提交、rust/lance/src/index/vector.rsVectorIndexParams与各索引构造方法性能基准rust/lance/benches 中提供了vector_index、ivf_pq、streaming_ivf_training、take、random_access、fts_search、merge_insert等数十个 Criterion 基准见 rust/lance/Cargo.toml可作为理解索引构建、随机访问与混合检索性能特性的参考。以上接口均以异步async方式提供需要 Tokio 运行时环境涉及对象存储的读写需要配置相应云厂商的凭据本地开发可直接使用文件系统路径作为 URI。【免费下载链接】lanceOpen Lakehouse Format for Multimodal AI. Convert from Parquet in 2 lines of code for 100x faster random access, vector index, and data versioning. Compatible with Pandas, DuckDB, Polars, Pyarrow, and PyTorch with more integrations coming..项目地址: https://gitcode.com/GitHub_Trending/la/lance创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门