Skip to content

Commit 6df5dd8

Browse files
committed
feat(quantization): expose uniform uint7 and add uint8
1 parent cb42297 commit 6df5dd8

21 files changed

Lines changed: 1139 additions & 163 deletions

src/core/interface/index.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,11 @@ int Index::CreateAndInitConverterReformer(const QuantizerParam &param,
180180
case QuantizerType::kRabitq:
181181
// no converter here
182182
return 0;
183-
case QuantizerType::kUniformInt8:
184-
converter_name = "UniformInt8StreamingConverter";
183+
case QuantizerType::kUniformUint7:
184+
converter_name = "UniformUint7StreamingConverter";
185+
break;
186+
case QuantizerType::kUniformUint8:
187+
converter_name = "UniformUint8StreamingConverter";
185188
break;
186189
default:
187190
LOG_ERROR("Unsupported quantizer type: ");

src/core/interface/index_param.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#include <string_view>
1516
#include <zvec/ailego/logger/logger.h>
1617
#include <zvec/core/interface/index_param.h>
1718
#include "core/interface/utils/utils.h"
@@ -340,4 +341,4 @@ bool QuantizerParam::DeserializeFromJsonObject(
340341

341342

342343
} // namespace core_interface
343-
} // namespace zvec
344+
} // namespace zvec

src/core/metric/metric_params.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,13 @@ static const std::string QUANTIZED_INTEGER_METRIC_ORIGIN_METRIC_NAME =
3434
static const std::string QUANTIZED_INTEGER_METRIC_ORIGIN_METRIC_PARAMS =
3535
"proxima.quantized_integer.metric.origin_metric_params";
3636

37-
//! UniformInt8 Metric
38-
static const std::string UNIFORM_INT8_METRIC_ORIGIN_METRIC_NAME =
39-
"proxima.uniform_int8.metric.origin_metric_name";
37+
//! UniformUint7 Metric
38+
static const std::string UNIFORM_UINT7_METRIC_ORIGIN_METRIC_NAME =
39+
"proxima.uniform_uint7.metric.origin_metric_name";
40+
41+
//! UniformUint8 Metric
42+
static const std::string UNIFORM_UINT8_METRIC_ORIGIN_METRIC_NAME =
43+
"proxima.uniform_uint8.metric.origin_metric_name";
4044

4145
} // namespace core
42-
} // namespace zvec
46+
} // namespace zvec
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,40 +22,40 @@
2222
namespace zvec {
2323
namespace core {
2424

25-
/*! Index Metric for Uniform Int8 Quantization (Global Scale)
25+
/*! Index Metric for Uniform Uint7 Quantization (Global Scale)
2626
*
2727
* Uses direct int8 L2 distance computation. Since all vectors share
2828
* a single global scale/bias, no per-vector reconstruction is needed.
2929
* This is the key benefit: distance = sum((a[i] - b[i])^2) on raw int8
3030
* values, with optional post-scaling by 1/scale^2 for real L2 distances.
3131
*/
32-
class UniformInt8Metric : public IndexMetric {
32+
class UniformUint7Metric : public IndexMetric {
3333
public:
3434
//! Initialize Metric
3535
int init(const IndexMeta &meta, const ailego::Params &index_params) override {
3636
if (meta.data_type() != IndexMeta::DataType::DT_INT8) {
37-
LOG_ERROR("UniformInt8Metric: unsupported type %d", meta.data_type());
37+
LOG_ERROR("UniformUint7Metric: unsupported type %d", meta.data_type());
3838
return IndexError_Unsupported;
3939
}
4040

4141
std::string metric_name;
42-
index_params.get(UNIFORM_INT8_METRIC_ORIGIN_METRIC_NAME, &metric_name);
42+
index_params.get(UNIFORM_UINT7_METRIC_ORIGIN_METRIC_NAME, &metric_name);
4343
if (metric_name.empty()) {
44-
LOG_ERROR("UniformInt8Metric: param %s is required",
45-
UNIFORM_INT8_METRIC_ORIGIN_METRIC_NAME.c_str());
44+
LOG_ERROR("UniformUint7Metric: param %s is required",
45+
UNIFORM_UINT7_METRIC_ORIGIN_METRIC_NAME.c_str());
4646
return IndexError_InvalidArgument;
4747
}
4848

4949
if (metric_name != "SquaredEuclidean") {
50-
LOG_ERROR("UniformInt8Metric: only SquaredEuclidean supported, got %s",
50+
LOG_ERROR("UniformUint7Metric: only SquaredEuclidean supported, got %s",
5151
metric_name.c_str());
5252
return IndexError_Unsupported;
5353
}
5454

5555
meta_ = meta;
5656
params_ = index_params;
5757

58-
LOG_INFO("UniformInt8Metric initialized: dimension=%u", meta_.dimension());
58+
LOG_INFO("UniformUint7Metric initialized: dimension=%u", meta_.dimension());
5959
return 0;
6060
}
6161

@@ -152,7 +152,7 @@ class UniformInt8Metric : public IndexMetric {
152152
ailego::Params params_{};
153153
};
154154

155-
INDEX_FACTORY_REGISTER_METRIC_ALIAS(UniformInt8, UniformInt8Metric);
155+
INDEX_FACTORY_REGISTER_METRIC_ALIAS(UniformUint7, UniformUint7Metric);
156156

157157
} // namespace core
158158
} // namespace zvec
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// Copyright 2025-present the zvec project
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <cstdint>
16+
#include <zvec/core/framework/index_error.h>
17+
#include <zvec/core/framework/index_factory.h>
18+
#include "metric_params.h"
19+
20+
namespace zvec {
21+
namespace core {
22+
23+
namespace {
24+
25+
void UniformUint8SquaredEuclidean(const void *lhs_data, const void *rhs_data,
26+
size_t dimension, float *distance) {
27+
const auto *lhs = static_cast<const int8_t *>(lhs_data);
28+
const auto *rhs = static_cast<const int8_t *>(rhs_data);
29+
int64_t sum = 0;
30+
for (size_t i = 0; i < dimension; ++i) {
31+
// Both operands store uint8 codes shifted by -128. Widen before
32+
// subtraction so the full [-255, 255] difference remains exact.
33+
const int difference = static_cast<int>(lhs[i]) - static_cast<int>(rhs[i]);
34+
sum += static_cast<int64_t>(difference) * difference;
35+
}
36+
*distance = static_cast<float>(sum);
37+
}
38+
39+
void UniformUint8SquaredEuclideanBatch(const void *const *vectors,
40+
const void *query, size_t count,
41+
size_t dimension, float *distances) {
42+
for (size_t i = 0; i < count; ++i) {
43+
UniformUint8SquaredEuclidean(vectors[i], query, dimension, distances + i);
44+
}
45+
}
46+
47+
} // namespace
48+
49+
class UniformUint8Metric : public IndexMetric {
50+
public:
51+
int init(const IndexMeta &meta, const ailego::Params &params) override {
52+
if (meta.data_type() != IndexMeta::DataType::DT_INT8) {
53+
LOG_ERROR("UniformUint8Metric: unsupported type %d", meta.data_type());
54+
return IndexError_Unsupported;
55+
}
56+
57+
std::string metric_name;
58+
params.get(UNIFORM_UINT8_METRIC_ORIGIN_METRIC_NAME, &metric_name);
59+
if (metric_name.empty()) {
60+
LOG_ERROR("UniformUint8Metric: param %s is required",
61+
UNIFORM_UINT8_METRIC_ORIGIN_METRIC_NAME.c_str());
62+
return IndexError_InvalidArgument;
63+
}
64+
if (metric_name != "SquaredEuclidean") {
65+
LOG_ERROR("UniformUint8Metric: only SquaredEuclidean supported, got %s",
66+
metric_name.c_str());
67+
return IndexError_Unsupported;
68+
}
69+
70+
meta_ = meta;
71+
params_ = params;
72+
return 0;
73+
}
74+
75+
int cleanup(void) override {
76+
return 0;
77+
}
78+
79+
bool is_matched(const IndexMeta &meta) const override {
80+
return meta.data_type() == meta_.data_type() &&
81+
meta.unit_size() == meta_.unit_size() &&
82+
meta.dimension() == meta_.dimension();
83+
}
84+
85+
bool is_matched(const IndexMeta &meta,
86+
const IndexQueryMeta &query_meta) const override {
87+
return is_matched(meta) && query_meta.data_type() == meta_.data_type() &&
88+
query_meta.unit_size() == meta_.unit_size() &&
89+
query_meta.dimension() == meta_.dimension();
90+
}
91+
92+
MatrixDistance distance(void) const override {
93+
return UniformUint8SquaredEuclidean;
94+
}
95+
96+
MatrixDistance distance_matrix(size_t rows, size_t columns) const override {
97+
return rows == 1 && columns == 1 ? UniformUint8SquaredEuclidean : nullptr;
98+
}
99+
100+
MatrixBatchDistance batch_distance(void) const override {
101+
return UniformUint8SquaredEuclideanBatch;
102+
}
103+
104+
const ailego::Params &params(void) const override {
105+
return params_;
106+
}
107+
108+
int train(const void * /*vector*/, size_t /*dimension*/) override {
109+
return 0;
110+
}
111+
112+
bool support_train(void) const override {
113+
return false;
114+
}
115+
116+
void normalize(float * /*score*/) const override {}
117+
118+
bool support_normalize(void) const override {
119+
return false;
120+
}
121+
122+
Pointer query_metric(void) const override {
123+
return nullptr;
124+
}
125+
126+
private:
127+
IndexMeta meta_{};
128+
ailego::Params params_{};
129+
};
130+
131+
INDEX_FACTORY_REGISTER_METRIC_ALIAS(UniformUint8, UniformUint8Metric);
132+
133+
} // namespace core
134+
} // namespace zvec

src/core/quantizer/quantizer_params.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,17 @@ static const std::string INTEGER_STREAMING_REFORMER_ENABLE_NORMALIZE =
119119
static const std::string INTEGER_STREAMING_REFORMER_IS_EUCLIDEAN =
120120
"integer_streaming.reformer.is_euclidean";
121121

122-
//! UniformInt8StreamingConverter / Reformer
123-
static const std::string UNIFORM_INT8_REFORMER_SCALE =
124-
"uniform_int8.reformer.scale";
125-
static const std::string UNIFORM_INT8_REFORMER_BIAS =
126-
"uniform_int8.reformer.bias";
122+
//! UniformUint7StreamingConverter / Reformer
123+
static const std::string UNIFORM_UINT7_REFORMER_SCALE =
124+
"uniform_uint7.reformer.scale";
125+
static const std::string UNIFORM_UINT7_REFORMER_BIAS =
126+
"uniform_uint7.reformer.bias";
127+
128+
//! UniformUint8StreamingConverter / Reformer
129+
static const std::string UNIFORM_UINT8_REFORMER_SCALE =
130+
"uniform_uint8.reformer.scale";
131+
static const std::string UNIFORM_UINT8_REFORMER_BIAS =
132+
"uniform_uint8.reformer.bias";
127133

128134
//! DoubleBitConverter
129135
static const std::string DOUBLE_BIT_CONVERTER_TRAIN_SAMPLE_COUNT =
@@ -140,4 +146,4 @@ static const std::string DOUBLE_BIT_REFORMER_B_VALUE =
140146
"double_bit.reformer.b_value";
141147

142148
} // namespace core
143-
} // namespace zvec
149+
} // namespace zvec

0 commit comments

Comments
 (0)