mirror of
https://github.com/qdrant/qdrant.git
synced 2026-07-26 04:31:02 -05:00
simplify edge config (#7933)
* simplify edge config * Accept default vector config or explicit vector config map when creating `EdgeConfig` * fixup! Accept default vector config or explicit vector config map when creating `EdgeConfig` Update examples * upd tests * bump edge version to v0.5.0 --------- Co-authored-by: Roman Titov <ffuugoo@users.noreply.github.com>
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -5315,7 +5315,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "qdrant-edge-py"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"bytemuck",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "qdrant-edge-py"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0"
|
||||
authors = ["Qdrant Team <info@qdrant.tech>"]
|
||||
license = "Apache-2.0"
|
||||
edition = "2024"
|
||||
|
||||
@@ -16,20 +16,11 @@ def load_new_shard():
|
||||
os.makedirs(DATA_DIRECTORY)
|
||||
|
||||
# Load Qdrant Edge shard
|
||||
config = SegmentConfig(
|
||||
vector_data={
|
||||
"": VectorDataConfig(
|
||||
size=4,
|
||||
distance=Distance.Dot,
|
||||
storage_type=VectorStorageType.ChunkedMmap,
|
||||
index=PlainIndexConfig(),
|
||||
quantization_config=None,
|
||||
multivector_config=None,
|
||||
datatype=None,
|
||||
),
|
||||
},
|
||||
sparse_vector_data={},
|
||||
payload_storage_type=PayloadStorageType.InRamMmap,
|
||||
config = EdgeConfig(
|
||||
vector_data=VectorDataConfig(
|
||||
size=4,
|
||||
distance=Distance.Dot
|
||||
)
|
||||
)
|
||||
|
||||
return EdgeShard(DATA_DIRECTORY, config)
|
||||
|
||||
@@ -147,4 +147,14 @@ print(f"Total points count: {count}")
|
||||
print("---- info ----")
|
||||
|
||||
info = shard.info()
|
||||
print(info)
|
||||
|
||||
print("---- Close and reopen shard ----")
|
||||
|
||||
shard.close()
|
||||
|
||||
reopened_shard = EdgeShard(DATA_DIRECTORY)
|
||||
|
||||
info = reopened_shard.info()
|
||||
|
||||
print(info)
|
||||
@@ -3,33 +3,27 @@
|
||||
from qdrant_edge import *
|
||||
|
||||
config = SegmentConfig(
|
||||
vector_data = {
|
||||
"": VectorDataConfig(
|
||||
size = 128,
|
||||
distance = Distance.Cosine,
|
||||
storage_type = VectorStorageType.ChunkedMmap,
|
||||
index = HnswIndexConfig(
|
||||
m = 16,
|
||||
ef_construct = 16,
|
||||
full_scan_threshold = 1024,
|
||||
on_disk = False,
|
||||
payload_m = 16,
|
||||
inline_storage = False,
|
||||
),
|
||||
)
|
||||
},
|
||||
vector_data = VectorDataConfig(
|
||||
size = 128,
|
||||
distance = Distance.Cosine,
|
||||
index = HnswIndexConfig(
|
||||
m = 16,
|
||||
ef_construct = 16,
|
||||
full_scan_threshold = 1024,
|
||||
on_disk = False,
|
||||
payload_m = 16,
|
||||
inline_storage = False,
|
||||
),
|
||||
),
|
||||
sparse_vector_data = {
|
||||
"sparse": SparseVectorDataConfig(
|
||||
index = SparseIndexConfig(
|
||||
full_scan_threshold = 1024,
|
||||
index_type = SparseIndexType.MutableRam,
|
||||
datatype = VectorStorageDatatype.Float32,
|
||||
),
|
||||
storage_type = SparseVectorStorageType.Mmap,
|
||||
modifier = Modifier.Idf,
|
||||
)
|
||||
},
|
||||
payload_storage_type = PayloadStorageType.Mmap,
|
||||
)
|
||||
|
||||
print(config)
|
||||
|
||||
@@ -15,24 +15,30 @@ pub use self::sparse_vector_data::*;
|
||||
pub use self::vector_data::*;
|
||||
use crate::repr::*;
|
||||
|
||||
#[pyclass(name = "SegmentConfig")]
|
||||
#[pyclass(name = "EdgeConfig")]
|
||||
#[derive(Clone, Debug, Into, TransparentWrapper)]
|
||||
#[repr(transparent)]
|
||||
pub struct PySegmentConfig(SegmentConfig);
|
||||
pub struct PyEdgeConfig(SegmentConfig);
|
||||
|
||||
#[pyclass_repr]
|
||||
#[pymethods]
|
||||
impl PySegmentConfig {
|
||||
impl PyEdgeConfig {
|
||||
#[new]
|
||||
#[pyo3(signature = (vector_data, sparse_vector_data=None))]
|
||||
pub fn new(
|
||||
#[pyo3(from_py_with = vector_data_config_helper)]
|
||||
// `vector_data_config_helper` accepts either
|
||||
// - a single default vector config: `VectorDataConfig(...)`
|
||||
// - or a map of named vector configs: `{ "": VectorDataConfig(...), "named_vector": VectorDataConfig(...) }`
|
||||
vector_data: HashMap<String, PyVectorDataConfig>,
|
||||
sparse_vector_data: HashMap<String, PySparseVectorDataConfig>,
|
||||
payload_storage_type: PyPayloadStorageType,
|
||||
sparse_vector_data: Option<HashMap<String, PySparseVectorDataConfig>>,
|
||||
) -> Self {
|
||||
Self(SegmentConfig {
|
||||
vector_data: PyVectorDataConfig::peel_map(vector_data),
|
||||
sparse_vector_data: PySparseVectorDataConfig::peel_map(sparse_vector_data),
|
||||
payload_storage_type: PayloadStorageType::from(payload_storage_type),
|
||||
sparse_vector_data: PySparseVectorDataConfig::peel_map(
|
||||
sparse_vector_data.unwrap_or_default(),
|
||||
),
|
||||
payload_storage_type: PayloadStorageType::Mmap,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -56,7 +62,7 @@ impl PySegmentConfig {
|
||||
}
|
||||
}
|
||||
|
||||
impl PySegmentConfig {
|
||||
impl PyEdgeConfig {
|
||||
fn _getters(self) {
|
||||
// Every field should have a getter method
|
||||
let SegmentConfig {
|
||||
@@ -111,3 +117,25 @@ impl From<PyPayloadStorageType> for PayloadStorageType {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn vector_data_config_helper(
|
||||
config: &Bound<'_, PyAny>,
|
||||
) -> PyResult<HashMap<String, PyVectorDataConfig>> {
|
||||
#[derive(FromPyObject)]
|
||||
enum Helper {
|
||||
Default(PyVectorDataConfig),
|
||||
Explicit(HashMap<String, PyVectorDataConfig>),
|
||||
}
|
||||
|
||||
let config = match config.extract()? {
|
||||
Helper::Default(default) => {
|
||||
let mut config = HashMap::new();
|
||||
config.insert("".into(), default);
|
||||
config
|
||||
}
|
||||
|
||||
Helper::Explicit(config) => config,
|
||||
};
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
@@ -36,15 +36,11 @@ impl PySparseVectorDataConfig {
|
||||
#[pymethods]
|
||||
impl PySparseVectorDataConfig {
|
||||
#[new]
|
||||
#[pyo3(signature = (index, storage_type, modifier = None))]
|
||||
pub fn new(
|
||||
index: PySparseIndexConfig,
|
||||
storage_type: PySparseVectorStorageType,
|
||||
modifier: Option<PyModifier>,
|
||||
) -> Self {
|
||||
#[pyo3(signature = (index, modifier = None))]
|
||||
pub fn new(index: PySparseIndexConfig, modifier: Option<PyModifier>) -> Self {
|
||||
Self(SparseVectorDataConfig {
|
||||
index: SparseIndexConfig::from(index),
|
||||
storage_type: SparseVectorStorageType::from(storage_type),
|
||||
storage_type: SparseVectorStorageType::Mmap,
|
||||
modifier: modifier.map(Modifier::from),
|
||||
})
|
||||
}
|
||||
@@ -99,14 +95,13 @@ pub struct PySparseIndexConfig(SparseIndexConfig);
|
||||
#[pymethods]
|
||||
impl PySparseIndexConfig {
|
||||
#[new]
|
||||
#[pyo3(signature = (index_type, full_scan_threshold = None, datatype = None))]
|
||||
#[pyo3(signature = (full_scan_threshold = None, datatype = None))]
|
||||
pub fn new(
|
||||
index_type: PySparseIndexType,
|
||||
full_scan_threshold: Option<usize>,
|
||||
datatype: Option<PyVectorStorageDatatype>,
|
||||
) -> Self {
|
||||
Self(SparseIndexConfig {
|
||||
index_type: SparseIndexType::from(index_type),
|
||||
index_type: SparseIndexType::MutableRam,
|
||||
full_scan_threshold,
|
||||
datatype: datatype.map(VectorStorageDatatype::from),
|
||||
})
|
||||
|
||||
@@ -35,12 +35,10 @@ impl PyVectorDataConfig {
|
||||
#[pymethods]
|
||||
impl PyVectorDataConfig {
|
||||
#[new]
|
||||
#[pyo3(signature = (size, distance, storage_type, index, quantization_config=None, multivector_config=None, datatype=None))]
|
||||
#[pyo3(signature = (size, distance, quantization_config=None, multivector_config=None, datatype=None))]
|
||||
pub fn new(
|
||||
size: usize,
|
||||
distance: PyDistance,
|
||||
storage_type: PyVectorStorageType,
|
||||
index: PyIndexes,
|
||||
quantization_config: Option<PyQuantizationConfig>,
|
||||
multivector_config: Option<PyMultiVectorConfig>,
|
||||
datatype: Option<PyVectorStorageDatatype>,
|
||||
@@ -48,8 +46,8 @@ impl PyVectorDataConfig {
|
||||
Self(VectorDataConfig {
|
||||
size,
|
||||
distance: Distance::from(distance),
|
||||
storage_type: VectorStorageType::from(storage_type),
|
||||
index: Indexes::from(index),
|
||||
storage_type: VectorStorageType::InRamChunkedMmap,
|
||||
index: Indexes::Plain {},
|
||||
quantization_config: quantization_config.map(QuantizationConfig::from),
|
||||
multivector_config: multivector_config.map(MultiVectorConfig::from),
|
||||
datatype: datatype.map(VectorStorageDatatype::from),
|
||||
|
||||
@@ -48,7 +48,7 @@ mod qdrant_edge {
|
||||
PyPlainIndexConfig, PyVectorDataConfig, PyVectorStorageDatatype, PyVectorStorageType,
|
||||
};
|
||||
#[pymodule_export]
|
||||
use super::config::{PyPayloadStorageType, PySegmentConfig};
|
||||
use super::config::{PyEdgeConfig, PyPayloadStorageType};
|
||||
#[pymodule_export]
|
||||
use super::count::PyCountRequest;
|
||||
#[pymodule_export]
|
||||
@@ -90,7 +90,7 @@ pub struct PyEdgeShard(Option<edge::EdgeShard>);
|
||||
impl PyEdgeShard {
|
||||
#[new]
|
||||
#[pyo3(signature = (path, config = None))]
|
||||
pub fn load(path: PathBuf, config: Option<PySegmentConfig>) -> Result<Self> {
|
||||
pub fn load(path: PathBuf, config: Option<PyEdgeConfig>) -> Result<Self> {
|
||||
let shard = edge::EdgeShard::load(&path, config.map(SegmentConfig::from))?;
|
||||
Ok(Self(Some(shard)))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user