Skip to content

Commit ec5e851

Browse files
committed
add quantization
1 parent 4d4add5 commit ec5e851

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2554
-334
lines changed

Cargo.lock

Lines changed: 15 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ base64 = "0.22"
261261
bincode = { version = "2.0.0-rc.3", features = ["serde", "std", "alloc"] }
262262
bincode_v1 = { package = "bincode", version = "1.3.3" }
263263
bitpacking = "0.8.0"
264+
bitvec = "1.0.1"
264265
blake3 = "1.3.1"
265266
bollard = { version = "0.17" }
266267
borsh = { version = "1.2.1", features = ["derive"] }
@@ -269,8 +270,7 @@ bstr = "1"
269270
buf-list = "1.0.3"
270271
bumpalo = "3.12.0"
271272
byte-unit = "5.1.6"
272-
#bytemuck = { version = "1", features = ["derive"] }
273-
bytemuck = { version = "1", features = ["derive", "extern_crate_alloc", "must_cast", "transparentwrapper_extra"] }
273+
bytemuck = { version = "1", features = ["derive"] }
274274
byteorder = "1.4.3"
275275
bytes = "1.5.0"
276276
bytesize = "1.1.0"
@@ -310,6 +310,7 @@ enumflags2 = { version = "0.7.7", features = ["serde"] }
310310
ethnum = { version = "1.5.1" }
311311
faststr = "0.2"
312312
feature-set = { version = "0.1.1" }
313+
feistel-permutation-rs = "0.1.1"
313314
flatbuffers = "25" # Must use the same version with arrow-ipc
314315
foreign_vec = "0.1.0"
315316
form_urlencoded = { version = "1" }
@@ -391,7 +392,7 @@ num = "0.4.0"
391392
num-bigint = "0.4.6"
392393
num-derive = "0.4.2"
393394
num-traits = "0.2.19"
394-
num_cpus = "1.13.1"
395+
num_cpus = "1.17"
395396
object = "0.36.5"
396397
object_store_opendal = { version = "0.52.0" }
397398
once_cell = "1.15.0"
@@ -470,6 +471,7 @@ rustls-pemfile = "2"
470471
rustls-pki-types = "1"
471472
rustyline = "14"
472473
scroll = "0.12.0"
474+
self_cell = "1.2.0"
473475
semver = "1.0.14"
474476
serde = { version = "1.0.164", features = ["derive", "rc"] }
475477
serde_derive = "1"
@@ -540,6 +542,7 @@ wiremock = "0.6"
540542
wkt = "0.11.1"
541543
xorf = { version = "0.11.0", default-features = false, features = ["binary-fuse"] }
542544
xorfilter-rs = "0.5"
545+
zerocopy = "0.8.26"
543546
zstd = "0.12.3"
544547

545548
# AST needed

src/common/metrics/src/metrics/storage.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,24 @@ static BLOCK_INVERTED_INDEX_READ_MILLISECONDS: LazyLock<Histogram> = LazyLock::n
177177
static BLOCK_INVERTED_INDEX_SEARCH_MILLISECONDS: LazyLock<Histogram> = LazyLock::new(|| {
178178
register_histogram_in_milliseconds("fuse_block_inverted_index_search_milliseconds")
179179
});
180+
static BLOCK_VECTOR_INDEX_WRITE_NUMS: LazyLock<Counter> =
181+
LazyLock::new(|| register_counter("fuse_block_vector_index_write_nums"));
182+
static BLOCK_VECTOR_INDEX_WRITE_BYTES: LazyLock<Counter> =
183+
LazyLock::new(|| register_counter("fuse_block_vector_index_write_bytes"));
184+
static BLOCK_VECTOR_INDEX_WRITE_MILLISECONDS: LazyLock<Histogram> = LazyLock::new(|| {
185+
register_histogram_in_milliseconds("fuse_block_vector_index_write_milliseconds")
186+
});
187+
static BLOCK_VECTOR_INDEX_GENERATE_MILLISECONDS: LazyLock<Histogram> = LazyLock::new(|| {
188+
register_histogram_in_milliseconds("fuse_block_vector_index_generate_milliseconds")
189+
});
190+
static BLOCK_VECTOR_INDEX_READ_MILLISECONDS: LazyLock<Histogram> = LazyLock::new(|| {
191+
register_histogram_in_milliseconds("fuse_block_vector_index_read_milliseconds")
192+
});
193+
static BLOCK_VECTOR_INDEX_SEARCH_MILLISECONDS: LazyLock<Histogram> = LazyLock::new(|| {
194+
register_histogram_in_milliseconds("fuse_block_vector_index_search_milliseconds")
195+
});
196+
static BLOCK_VECTOR_INDEX_READ_BYTES: LazyLock<Counter> =
197+
LazyLock::new(|| register_counter("fuse_block_vector_index_read_bytes"));
180198
static COMPACT_BLOCK_READ_NUMS: LazyLock<Counter> =
181199
LazyLock::new(|| register_counter("fuse_compact_block_read_nums"));
182200
static COMPACT_BLOCK_READ_BYTES: LazyLock<Counter> =
@@ -548,6 +566,10 @@ pub fn metrics_inc_block_index_write_bytes(c: u64) {
548566
BLOCK_INDEX_WRITE_BYTES.inc_by(c);
549567
}
550568

569+
pub fn metrics_inc_block_index_read_bytes(c: u64) {
570+
BLOCK_INDEX_READ_BYTES.inc_by(c);
571+
}
572+
551573
pub fn metrics_inc_block_index_write_milliseconds(c: u64) {
552574
BLOCK_INDEX_WRITE_MILLISECONDS.observe(c as f64);
553575
}
@@ -576,8 +598,32 @@ pub fn metrics_inc_block_inverted_index_search_milliseconds(c: u64) {
576598
BLOCK_INVERTED_INDEX_SEARCH_MILLISECONDS.observe(c as f64);
577599
}
578600

579-
pub fn metrics_inc_block_index_read_bytes(c: u64) {
580-
BLOCK_INDEX_READ_BYTES.inc_by(c);
601+
pub fn metrics_inc_block_vector_index_write_nums(c: u64) {
602+
BLOCK_VECTOR_INDEX_WRITE_NUMS.inc_by(c);
603+
}
604+
605+
pub fn metrics_inc_block_vector_index_write_bytes(c: u64) {
606+
BLOCK_VECTOR_INDEX_WRITE_BYTES.inc_by(c);
607+
}
608+
609+
pub fn metrics_inc_block_vector_index_write_milliseconds(c: u64) {
610+
BLOCK_VECTOR_INDEX_WRITE_MILLISECONDS.observe(c as f64);
611+
}
612+
613+
pub fn metrics_inc_block_vector_index_generate_milliseconds(c: u64) {
614+
BLOCK_VECTOR_INDEX_GENERATE_MILLISECONDS.observe(c as f64);
615+
}
616+
617+
pub fn metrics_inc_block_vector_index_read_milliseconds(c: u64) {
618+
BLOCK_VECTOR_INDEX_READ_MILLISECONDS.observe(c as f64);
619+
}
620+
621+
pub fn metrics_inc_block_vector_index_search_milliseconds(c: u64) {
622+
BLOCK_VECTOR_INDEX_SEARCH_MILLISECONDS.observe(c as f64);
623+
}
624+
625+
pub fn metrics_inc_block_vector_index_read_bytes(c: u64) {
626+
BLOCK_VECTOR_INDEX_READ_BYTES.inc_by(c);
581627
}
582628

583629
/// Compact metrics.

src/common/vector/src/distance.rs

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,69 +16,101 @@ use databend_common_exception::ErrorCode;
1616
use databend_common_exception::Result;
1717
use ndarray::ArrayView;
1818

19-
pub fn cosine_distance(from: &[f32], to: &[f32]) -> Result<f32> {
20-
if from.len() != to.len() {
19+
pub fn cosine_distance(lhs: &[f32], rhs: &[f32]) -> Result<f32> {
20+
if lhs.len() != rhs.len() {
2121
return Err(ErrorCode::InvalidArgument(format!(
2222
"Vector length not equal: {:} != {:}",
23-
from.len(),
24-
to.len(),
23+
lhs.len(),
24+
rhs.len(),
2525
)));
2626
}
2727

28-
let a = ArrayView::from(from);
29-
let b = ArrayView::from(to);
28+
let a = ArrayView::from(lhs);
29+
let b = ArrayView::from(rhs);
3030
let aa_sum = (&a * &a).sum();
3131
let bb_sum = (&b * &b).sum();
3232

3333
Ok(1.0 - (&a * &b).sum() / ((aa_sum).sqrt() * (bb_sum).sqrt()))
3434
}
3535

36-
pub fn l2_distance(from: &[f32], to: &[f32]) -> Result<f32> {
37-
if from.len() != to.len() {
36+
pub fn l1_distance(lhs: &[f32], rhs: &[f32]) -> Result<f32> {
37+
if lhs.len() != rhs.len() {
3838
return Err(ErrorCode::InvalidArgument(format!(
3939
"Vector length not equal: {:} != {:}",
40-
from.len(),
41-
to.len(),
40+
lhs.len(),
41+
rhs.len(),
4242
)));
4343
}
4444

45-
Ok(from
45+
Ok(lhs
4646
.iter()
47-
.zip(to.iter())
47+
.zip(rhs.iter())
48+
.map(|(a, b)| (a - b).abs())
49+
.sum::<f32>())
50+
}
51+
52+
pub fn l2_distance(lhs: &[f32], rhs: &[f32]) -> Result<f32> {
53+
if lhs.len() != rhs.len() {
54+
return Err(ErrorCode::InvalidArgument(format!(
55+
"Vector length not equal: {:} != {:}",
56+
lhs.len(),
57+
rhs.len(),
58+
)));
59+
}
60+
61+
Ok(lhs
62+
.iter()
63+
.zip(rhs.iter())
4864
.map(|(a, b)| (a - b).powi(2))
4965
.sum::<f32>()
5066
.sqrt())
5167
}
5268

53-
pub fn cosine_distance_64(from: &[f64], to: &[f64]) -> Result<f64> {
54-
if from.len() != to.len() {
69+
pub fn cosine_distance_64(lhs: &[f64], rhs: &[f64]) -> Result<f64> {
70+
if lhs.len() != rhs.len() {
5571
return Err(ErrorCode::InvalidArgument(format!(
5672
"Vector length not equal: {:} != {:}",
57-
from.len(),
58-
to.len(),
73+
lhs.len(),
74+
rhs.len(),
5975
)));
6076
}
6177

62-
let a = ArrayView::from(from);
63-
let b = ArrayView::from(to);
78+
let a = ArrayView::from(lhs);
79+
let b = ArrayView::from(rhs);
6480
let aa_sum = (&a * &a).sum();
6581
let bb_sum = (&b * &b).sum();
6682

6783
Ok(1.0 - (&a * &b).sum() / ((aa_sum).sqrt() * (bb_sum).sqrt()))
6884
}
6985

70-
pub fn l2_distance_64(from: &[f64], to: &[f64]) -> Result<f64> {
71-
if from.len() != to.len() {
86+
pub fn l1_distance_64(lhs: &[f64], rhs: &[f64]) -> Result<f64> {
87+
if lhs.len() != rhs.len() {
88+
return Err(ErrorCode::InvalidArgument(format!(
89+
"Vector length not equal: {:} != {:}",
90+
lhs.len(),
91+
rhs.len(),
92+
)));
93+
}
94+
95+
Ok(lhs
96+
.iter()
97+
.zip(rhs.iter())
98+
.map(|(a, b)| (a - b).abs())
99+
.sum::<f64>())
100+
}
101+
102+
pub fn l2_distance_64(lhs: &[f64], rhs: &[f64]) -> Result<f64> {
103+
if lhs.len() != rhs.len() {
72104
return Err(ErrorCode::InvalidArgument(format!(
73105
"Vector length not equal: {:} != {:}",
74-
from.len(),
75-
to.len(),
106+
lhs.len(),
107+
rhs.len(),
76108
)));
77109
}
78110

79-
Ok(from
111+
Ok(lhs
80112
.iter()
81-
.zip(to.iter())
113+
.zip(rhs.iter())
82114
.map(|(a, b)| (a - b).powi(2))
83115
.sum::<f64>()
84116
.sqrt())

src/common/vector/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@ mod distance;
1616

1717
pub use distance::cosine_distance;
1818
pub use distance::cosine_distance_64;
19+
pub use distance::l1_distance;
20+
pub use distance::l1_distance_64;
1921
pub use distance::l2_distance;
2022
pub use distance::l2_distance_64;

src/query/catalog/src/plan/internal_column.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ use databend_common_expression::SEARCH_MATCHED_COLUMN_ID;
4242
use databend_common_expression::SEARCH_SCORE_COLUMN_ID;
4343
use databend_common_expression::SEGMENT_NAME_COLUMN_ID;
4444
use databend_common_expression::SNAPSHOT_NAME_COLUMN_ID;
45+
use databend_common_expression::VECTOR_SCORE_COLUMN_ID;
4546
use databend_storages_common_table_meta::meta::try_extract_uuid_str_from_path;
4647
use databend_storages_common_table_meta::meta::NUM_BLOCK_ID_BITS;
4748

@@ -106,6 +107,8 @@ pub struct InternalColumnMeta {
106107
pub inner: Option<BlockMetaInfoPtr>,
107108
// The search matched rows and optional scores in the block.
108109
pub matched_rows: Option<Vec<(usize, Option<F32>)>>,
110+
// The vector topn rows and scores in the block.
111+
pub vector_scores: Option<Vec<(usize, F32)>>,
109112
}
110113

111114
#[typetag::serde(name = "internal_column_meta")]
@@ -142,6 +145,9 @@ pub enum InternalColumnType {
142145
SearchMatched,
143146
SearchScore,
144147

148+
// vector columns
149+
VectorScore,
150+
145151
FileName,
146152
FileRowNumber,
147153
}
@@ -176,6 +182,7 @@ impl InternalColumn {
176182
)),
177183
InternalColumnType::SearchMatched => TableDataType::Boolean,
178184
InternalColumnType::SearchScore => TableDataType::Number(NumberDataType::Float32),
185+
InternalColumnType::VectorScore => TableDataType::Number(NumberDataType::Float32),
179186
InternalColumnType::FileName => TableDataType::String,
180187
InternalColumnType::FileRowNumber => TableDataType::Number(NumberDataType::UInt64),
181188
}
@@ -200,6 +207,7 @@ impl InternalColumn {
200207
InternalColumnType::BaseBlockIds => BASE_BLOCK_IDS_COLUMN_ID,
201208
InternalColumnType::SearchMatched => SEARCH_MATCHED_COLUMN_ID,
202209
InternalColumnType::SearchScore => SEARCH_SCORE_COLUMN_ID,
210+
InternalColumnType::VectorScore => VECTOR_SCORE_COLUMN_ID,
203211
InternalColumnType::FileName => FILENAME_COLUMN_ID,
204212
InternalColumnType::FileRowNumber => FILE_ROW_NUMBER_COLUMN_ID,
205213
}
@@ -291,6 +299,20 @@ impl InternalColumn {
291299
}
292300
Float32Type::from_data(scores).into()
293301
}
302+
InternalColumnType::VectorScore => {
303+
assert!(meta.vector_scores.is_some());
304+
let vector_scores = meta.vector_scores.as_ref().unwrap();
305+
306+
// The smaller the score, the closer the distance.
307+
// Fill other rows with the maximum value and they will be filtered out.
308+
let mut scores = vec![F32::from(f32::MAX); num_rows];
309+
for (idx, score) in vector_scores.iter() {
310+
if let Some(val) = scores.get_mut(*idx) {
311+
*val = *score;
312+
}
313+
}
314+
Float32Type::from_data(scores).into()
315+
}
294316
InternalColumnType::FileName | InternalColumnType::FileRowNumber => {
295317
todo!("generate_column_values not support for file related")
296318
}

0 commit comments

Comments
 (0)