mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-06 17:18:35 +08:00
Add binary metric types SUBSTRUCTURE/SUPERSTRUCTURE back (#26766)
Signed-off-by: Yudong Cai <yudong.cai@zilliz.com>
This commit is contained in:
parent
aad3d47a06
commit
8dc16b599b
@ -20,4 +20,6 @@ TEST(SimilarityCorelation, Naive) {
|
||||
ASSERT_FALSE(milvus::PositivelyRelated(knowhere::metric::L2));
|
||||
ASSERT_FALSE(milvus::PositivelyRelated(knowhere::metric::HAMMING));
|
||||
ASSERT_FALSE(milvus::PositivelyRelated(knowhere::metric::JACCARD));
|
||||
ASSERT_FALSE(milvus::PositivelyRelated(knowhere::metric::SUBSTRUCTURE));
|
||||
ASSERT_FALSE(milvus::PositivelyRelated(knowhere::metric::SUPERSTRUCTURE));
|
||||
}
|
||||
|
||||
@ -446,7 +446,7 @@ func validateMetricType(dataType schemapb.DataType, metricTypeStrRaw string) err
|
||||
if dataType == schemapb.DataType_FloatVector {
|
||||
return nil
|
||||
}
|
||||
case metric.JACCARD, metric.HAMMING:
|
||||
case metric.JACCARD, metric.HAMMING, metric.SUBSTRUCTURE, metric.SUPERSTRUCTURE:
|
||||
if dataType == schemapb.DataType_BinaryVector {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@ func Test_binFlatChecker_CheckTrain(t *testing.T) {
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.COSINE,
|
||||
}
|
||||
|
||||
p4 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.HAMMING,
|
||||
@ -39,6 +40,14 @@ func Test_binFlatChecker_CheckTrain(t *testing.T) {
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.JACCARD,
|
||||
}
|
||||
p6 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.SUBSTRUCTURE,
|
||||
}
|
||||
p7 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.SUPERSTRUCTURE,
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
params map[string]string
|
||||
@ -51,6 +60,8 @@ func Test_binFlatChecker_CheckTrain(t *testing.T) {
|
||||
{p3, false},
|
||||
{p4, true},
|
||||
{p5, true},
|
||||
{p6, true},
|
||||
{p7, true},
|
||||
}
|
||||
|
||||
c := newBinFlatChecker()
|
||||
|
||||
@ -9,8 +9,8 @@ type binIVFFlatChecker struct {
|
||||
}
|
||||
|
||||
func (c binIVFFlatChecker) StaticCheck(params map[string]string) error {
|
||||
if !CheckStrByValues(params, Metric, BinMetrics) {
|
||||
return fmt.Errorf("metric type not found or not supported, supported: %v", BinMetrics)
|
||||
if !CheckStrByValues(params, Metric, BinIvfMetrics) {
|
||||
return fmt.Errorf("metric type not found or not supported, supported: %v", BinIvfMetrics)
|
||||
}
|
||||
|
||||
if !CheckIntByRange(params, NLIST, MinNList, MaxNList) {
|
||||
|
||||
@ -65,6 +65,7 @@ func Test_binIVFFlatChecker_CheckTrain(t *testing.T) {
|
||||
IVFM: strconv.Itoa(4),
|
||||
NBITS: strconv.Itoa(8),
|
||||
}
|
||||
|
||||
p4 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.HAMMING,
|
||||
@ -79,6 +80,20 @@ func Test_binIVFFlatChecker_CheckTrain(t *testing.T) {
|
||||
IVFM: strconv.Itoa(4),
|
||||
NBITS: strconv.Itoa(8),
|
||||
}
|
||||
p6 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.SUBSTRUCTURE,
|
||||
NLIST: strconv.Itoa(100),
|
||||
IVFM: strconv.Itoa(4),
|
||||
NBITS: strconv.Itoa(8),
|
||||
}
|
||||
p7 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.SUPERSTRUCTURE,
|
||||
NLIST: strconv.Itoa(100),
|
||||
IVFM: strconv.Itoa(4),
|
||||
NBITS: strconv.Itoa(8),
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
params map[string]string
|
||||
@ -96,6 +111,8 @@ func Test_binIVFFlatChecker_CheckTrain(t *testing.T) {
|
||||
|
||||
{p4, true},
|
||||
{p5, true},
|
||||
{p6, false},
|
||||
{p7, false},
|
||||
}
|
||||
|
||||
c := newBinIVFFlatChecker()
|
||||
|
||||
@ -13,8 +13,8 @@ type binaryVectorBaseChecker struct {
|
||||
}
|
||||
|
||||
func (c binaryVectorBaseChecker) staticCheck(params map[string]string) error {
|
||||
if !CheckStrByValues(params, Metric, BinMetrics) {
|
||||
return fmt.Errorf("metric type not found or not supported, supported: %v", BinMetrics)
|
||||
if !CheckStrByValues(params, Metric, BinIDMapMetrics) {
|
||||
return fmt.Errorf("metric type not found or not supported, supported: %v", BinIDMapMetrics)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@ -42,10 +42,11 @@ const (
|
||||
var METRICS = []string{metric.L2, metric.IP, metric.COSINE} // const
|
||||
|
||||
// BinIDMapMetrics is a set of all metric types supported for binary vector.
|
||||
var BinMetrics = []string{metric.HAMMING, metric.JACCARD} // const
|
||||
var HnswMetrics = []string{metric.L2, metric.IP, metric.COSINE, metric.HAMMING, metric.JACCARD} // const
|
||||
var supportDimPerSubQuantizer = []int{32, 28, 24, 20, 16, 12, 10, 8, 6, 4, 3, 2, 1} // const
|
||||
var supportSubQuantizer = []int{96, 64, 56, 48, 40, 32, 28, 24, 20, 16, 12, 8, 4, 3, 2, 1} // const
|
||||
var BinIDMapMetrics = []string{metric.HAMMING, metric.JACCARD, metric.SUBSTRUCTURE, metric.SUPERSTRUCTURE} // const
|
||||
var BinIvfMetrics = []string{metric.HAMMING, metric.JACCARD} // const
|
||||
var HnswMetrics = []string{metric.L2, metric.IP, metric.COSINE, metric.HAMMING, metric.JACCARD} // const
|
||||
var supportDimPerSubQuantizer = []int{32, 28, 24, 20, 16, 12, 10, 8, 6, 4, 3, 2, 1} // const
|
||||
var supportSubQuantizer = []int{96, 64, 56, 48, 40, 32, 28, 24, 20, 16, 12, 8, 4, 3, 2, 1} // const
|
||||
|
||||
const (
|
||||
FloatVectorDefaultMetricType = metric.IP
|
||||
|
||||
@ -37,6 +37,7 @@ func Test_diskannChecker_CheckTrain(t *testing.T) {
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.COSINE,
|
||||
}
|
||||
|
||||
p4 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.HAMMING,
|
||||
@ -45,6 +46,14 @@ func Test_diskannChecker_CheckTrain(t *testing.T) {
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.JACCARD,
|
||||
}
|
||||
p6 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.SUBSTRUCTURE,
|
||||
}
|
||||
p7 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.SUPERSTRUCTURE,
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
params map[string]string
|
||||
@ -59,6 +68,8 @@ func Test_diskannChecker_CheckTrain(t *testing.T) {
|
||||
{p3, true},
|
||||
{p4, false},
|
||||
{p5, false},
|
||||
{p6, false},
|
||||
{p7, false},
|
||||
}
|
||||
|
||||
c := newDiskannChecker()
|
||||
|
||||
@ -23,6 +23,7 @@ func Test_flatChecker_CheckTrain(t *testing.T) {
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.COSINE,
|
||||
}
|
||||
|
||||
p4 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.HAMMING,
|
||||
@ -31,7 +32,14 @@ func Test_flatChecker_CheckTrain(t *testing.T) {
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.JACCARD,
|
||||
}
|
||||
|
||||
p6 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.SUBSTRUCTURE,
|
||||
}
|
||||
p7 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
Metric: metric.SUPERSTRUCTURE,
|
||||
}
|
||||
cases := []struct {
|
||||
params map[string]string
|
||||
errIsNil bool
|
||||
@ -41,6 +49,8 @@ func Test_flatChecker_CheckTrain(t *testing.T) {
|
||||
{p3, true},
|
||||
{p4, false},
|
||||
{p5, false},
|
||||
{p6, false},
|
||||
{p7, false},
|
||||
}
|
||||
|
||||
c := newFlatChecker()
|
||||
|
||||
@ -49,6 +49,7 @@ func Test_hnswChecker_CheckTrain(t *testing.T) {
|
||||
EFConstruction: strconv.Itoa(200),
|
||||
Metric: metric.COSINE,
|
||||
}
|
||||
|
||||
p4 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
HNSWM: strconv.Itoa(16),
|
||||
@ -61,6 +62,18 @@ func Test_hnswChecker_CheckTrain(t *testing.T) {
|
||||
EFConstruction: strconv.Itoa(200),
|
||||
Metric: metric.JACCARD,
|
||||
}
|
||||
p6 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
HNSWM: strconv.Itoa(16),
|
||||
EFConstruction: strconv.Itoa(200),
|
||||
Metric: metric.SUBSTRUCTURE,
|
||||
}
|
||||
p7 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
HNSWM: strconv.Itoa(16),
|
||||
EFConstruction: strconv.Itoa(200),
|
||||
Metric: metric.SUPERSTRUCTURE,
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
params map[string]string
|
||||
@ -76,6 +89,8 @@ func Test_hnswChecker_CheckTrain(t *testing.T) {
|
||||
{p3, true},
|
||||
{p4, true},
|
||||
{p5, true},
|
||||
{p6, false},
|
||||
{p7, false},
|
||||
}
|
||||
|
||||
c := newHnswChecker()
|
||||
|
||||
@ -32,6 +32,7 @@ func Test_ivfBaseChecker_CheckTrain(t *testing.T) {
|
||||
NLIST: strconv.Itoa(1024),
|
||||
Metric: metric.COSINE,
|
||||
}
|
||||
|
||||
p4 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
NLIST: strconv.Itoa(1024),
|
||||
@ -42,6 +43,16 @@ func Test_ivfBaseChecker_CheckTrain(t *testing.T) {
|
||||
NLIST: strconv.Itoa(1024),
|
||||
Metric: metric.JACCARD,
|
||||
}
|
||||
p6 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
NLIST: strconv.Itoa(1024),
|
||||
Metric: metric.SUBSTRUCTURE,
|
||||
}
|
||||
p7 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
NLIST: strconv.Itoa(1024),
|
||||
Metric: metric.SUPERSTRUCTURE,
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
params map[string]string
|
||||
@ -55,6 +66,8 @@ func Test_ivfBaseChecker_CheckTrain(t *testing.T) {
|
||||
{p3, true},
|
||||
{p4, false},
|
||||
{p5, false},
|
||||
{p6, false},
|
||||
{p7, false},
|
||||
}
|
||||
|
||||
c := newIVFBaseChecker()
|
||||
|
||||
@ -84,6 +84,7 @@ func Test_ivfPQChecker_CheckTrain(t *testing.T) {
|
||||
NBITS: strconv.Itoa(8),
|
||||
Metric: metric.COSINE,
|
||||
}
|
||||
|
||||
p4 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
NLIST: strconv.Itoa(1024),
|
||||
@ -98,6 +99,20 @@ func Test_ivfPQChecker_CheckTrain(t *testing.T) {
|
||||
NBITS: strconv.Itoa(8),
|
||||
Metric: metric.JACCARD,
|
||||
}
|
||||
p6 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
NLIST: strconv.Itoa(1024),
|
||||
IVFM: strconv.Itoa(4),
|
||||
NBITS: strconv.Itoa(8),
|
||||
Metric: metric.SUBSTRUCTURE,
|
||||
}
|
||||
p7 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
NLIST: strconv.Itoa(1024),
|
||||
IVFM: strconv.Itoa(4),
|
||||
NBITS: strconv.Itoa(8),
|
||||
Metric: metric.SUPERSTRUCTURE,
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
params map[string]string
|
||||
@ -120,6 +135,8 @@ func Test_ivfPQChecker_CheckTrain(t *testing.T) {
|
||||
{p3, true},
|
||||
{p4, false},
|
||||
{p5, false},
|
||||
{p6, false},
|
||||
{p7, false},
|
||||
}
|
||||
|
||||
c := newIVFPQChecker()
|
||||
|
||||
@ -46,6 +46,7 @@ func Test_ivfSQChecker_CheckTrain(t *testing.T) {
|
||||
NBITS: strconv.Itoa(8),
|
||||
Metric: metric.COSINE,
|
||||
}
|
||||
|
||||
p4 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
NLIST: strconv.Itoa(100),
|
||||
@ -58,6 +59,18 @@ func Test_ivfSQChecker_CheckTrain(t *testing.T) {
|
||||
NBITS: strconv.Itoa(8),
|
||||
Metric: metric.JACCARD,
|
||||
}
|
||||
p6 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
NLIST: strconv.Itoa(100),
|
||||
NBITS: strconv.Itoa(8),
|
||||
Metric: metric.SUBSTRUCTURE,
|
||||
}
|
||||
p7 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
NLIST: strconv.Itoa(100),
|
||||
NBITS: strconv.Itoa(8),
|
||||
Metric: metric.SUPERSTRUCTURE,
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
params map[string]string
|
||||
@ -73,6 +86,8 @@ func Test_ivfSQChecker_CheckTrain(t *testing.T) {
|
||||
{p3, true},
|
||||
{p4, false},
|
||||
{p5, false},
|
||||
{p6, false},
|
||||
{p7, false},
|
||||
}
|
||||
|
||||
c := newIVFSQChecker()
|
||||
|
||||
@ -77,6 +77,7 @@ func Test_raftIVFPQChecker_CheckTrain(t *testing.T) {
|
||||
NBITS: strconv.Itoa(8),
|
||||
Metric: metric.COSINE,
|
||||
}
|
||||
|
||||
p4 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
NLIST: strconv.Itoa(1024),
|
||||
@ -91,6 +92,20 @@ func Test_raftIVFPQChecker_CheckTrain(t *testing.T) {
|
||||
NBITS: strconv.Itoa(8),
|
||||
Metric: metric.JACCARD,
|
||||
}
|
||||
p6 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
NLIST: strconv.Itoa(1024),
|
||||
IVFM: strconv.Itoa(4),
|
||||
NBITS: strconv.Itoa(8),
|
||||
Metric: metric.SUBSTRUCTURE,
|
||||
}
|
||||
p7 := map[string]string{
|
||||
DIM: strconv.Itoa(128),
|
||||
NLIST: strconv.Itoa(1024),
|
||||
IVFM: strconv.Itoa(4),
|
||||
NBITS: strconv.Itoa(8),
|
||||
Metric: metric.SUPERSTRUCTURE,
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
params map[string]string
|
||||
@ -112,6 +127,8 @@ func Test_raftIVFPQChecker_CheckTrain(t *testing.T) {
|
||||
{p3, true},
|
||||
{p4, false},
|
||||
{p5, false},
|
||||
{p6, false},
|
||||
{p7, false},
|
||||
}
|
||||
|
||||
c := newRaftIVFPQChecker()
|
||||
|
||||
@ -30,4 +30,10 @@ const (
|
||||
|
||||
// JACCARD represents jaccard distance
|
||||
JACCARD MetricType = "JACCARD"
|
||||
|
||||
// SUBSTRUCTURE represents substructure distance
|
||||
SUBSTRUCTURE MetricType = "SUBSTRUCTURE"
|
||||
|
||||
// SUPERSTRUCTURE represents superstructure distance
|
||||
SUPERSTRUCTURE MetricType = "SUPERSTRUCTURE"
|
||||
)
|
||||
|
||||
@ -43,6 +43,14 @@ func TestPositivelyRelated(t *testing.T) {
|
||||
JACCARD,
|
||||
false,
|
||||
},
|
||||
{
|
||||
SUBSTRUCTURE,
|
||||
false,
|
||||
},
|
||||
{
|
||||
SUPERSTRUCTURE,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for idx := range cases {
|
||||
|
||||
@ -239,7 +239,7 @@ delete_support = ["FLAT", "IVF_FLAT", "IVF_SQ8", "IVF_PQ"]
|
||||
ivf = ["FLAT", "IVF_FLAT", "IVF_SQ8", "IVF_PQ"]
|
||||
skip_pq = ["IVF_PQ"]
|
||||
float_metrics = ["L2", "IP", "COSINE"]
|
||||
binary_metrics = ["JACCARD", "HAMMING"]
|
||||
binary_metrics = ["JACCARD", "HAMMING", "SUBSTRUCTURE", "SUPERSTRUCTURE"]
|
||||
structure_metrics = ["SUBSTRUCTURE", "SUPERSTRUCTURE"]
|
||||
all_scalar_data_types = ['int8', 'int16', 'int32', 'int64', 'float', 'double', 'bool', 'varchar']
|
||||
|
||||
|
||||
@ -75,7 +75,7 @@ def skip_pq():
|
||||
|
||||
|
||||
def binary_metrics():
|
||||
return ["JACCARD", "HAMMING"]
|
||||
return ["JACCARD", "HAMMING", "SUBSTRUCTURE", "SUPERSTRUCTURE"]
|
||||
|
||||
|
||||
def structure_metrics():
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user