当前位置: 首页 > news >正文

faiss库中ivf-sq(ScalarQuantizer,标量量化)代码解读-2

文件ScalarQuantizer.h

主要介绍这里面的枚举以及一些函数内容:QuantizerType、RangeStat、ScalarQuantizer、train、compute_codes、decode、SQuantizer、FlatCodesDistanceComputer、get_distance_computer、select_InvertedListScanner

QuantizerType

量化类型中包含一些枚举类型,代码内容如下:

enum QuantizerType {QT_8bit,         ///< 8 bits per componentQT_4bit,         ///< 4 bits per componentQT_8bit_uniform, ///< same, shared range for all dimensionsQT_4bit_uniform,QT_fp16,QT_8bit_direct, ///< fast indexing of uint8sQT_6bit,        ///< 6 bits per componentQT_bf16,QT_8bit_direct_signed, ///< fast indexing of signed int8s ranging from///< [-128 to 127]};

QuantizerType 枚举内容解析

枚举值描述适用场景
QT_8bit每个分量用 8-bit 表示,分量间有独立范围(非均匀量化)。精度较高,适用于一般场景。
QT_4bit每个分量用 4-bit 表示,分量间有独立范围(非均匀量化)。精度较低但压缩率高,适用于存储敏感的大规模数据。
QT_8bit_uniform每个分量用 8-bit 表示,但所有分量共享一个范围(均匀量化)。适合数据分布较均匀的场景,计算简单,存储开销低。
QT_4bit_uniform每个分量用 4-bit 表示,所有分量共享一个范围(均匀量化)。存储极为节省,但精度较低,适合快速粗筛。
QT_fp16每个分量用 16-bit 浮点数(half-precision floating-point) 表示。高精度场景,兼顾压缩率和精度,但存储开销大于 8-bit 和 4-bit。
QT_8bit_direct直接使用无符号 uint8 值,无需量化,直接存储整数。数据本身就是无符号 8-bit 整数,例如像素值。
QT_6bit每个分量用 6-bit 表示,比 8-bit 压缩但比 4-bit 精度更高。存储与精度需求的折中选择,适合数据分布复杂但存储受限的场景。
QT_bf16使用 bfloat16(16-bit 浮点数) 表示,范围与精度介于 fp16 和 uint8 之间。适用于高动态范围但对精度要求不高的场景,例如部分深度学习推理中。
QT_8bit_direct_signed直接使用有符号 int8 值,无需量化,范围为 [-128, 127]。数据本身就是有符号的整数,例如分量可能包含负值的数据。

为什么设置为这些类型?

支持不同的精度需求

  • 数据量化需要在存储成本与精度之间找到平衡,不同类型的量化方式提供了不同的压缩率和精度。
    • 8-bit 和 4-bit:提供了常见的两种量化方式,适合大多数存储需求。
    • 6-bit:为 8-bit 和 4-bit 之间提供折中选择。
    • fp16 和 bf16:用于精度较高的场景,支持浮点值表示。
      适配多种数据分布
    • 有些数据在不同维度的范围不同(非均匀分布),需要 非均匀量化(如 QT_8bit 和 QT_4bit)。
    • 对于范围均匀的数据,可以使用 均匀量化(如 QT_8bit_uniform 和 QT_4bit_uniform),进一步减少存储复杂性。
      提高存储效率
    • QT_4bit 和 QT_4bit_uniform:只用 4-bit 表示每个分量,适合存储空间受限的大规模向量。
    • QT_6bit:比 8-bit 进一步压缩,但比 4-bit 提供更高精度。
      兼容特殊数据类型
    • QT_8bit_direct 和 QT_8bit_direct_signed:直接存储原始值,不需要量化过程,适合已经量化好的数据或离散整数值。

RangeStat

代码内容如下:

enum RangeStat {RS_minmax,    ///< [min - rs*(max-min), max + rs*(max-min)]RS_meanstd,   ///< [mean - std * rs, mean + std * rs]RS_quantiles, ///< [Q(rs), Q(1-rs)]RS_optim,     ///< alternate optimization of reconstruction error
};
枚举值描述用途与适用场景
RS_minmax根据向量的最小值和最大值生成范围:
[ min - rs * (max - min), max + rs * (max - min) ]。
- 数据分布均匀的场景
- 快速计算,但对异常值较为敏感。
RS_meanstd根据向量的均值和标准差生成范围:
[ mean - std * rs, mean + std * rs ]。
- 考虑数据集中趋势和离散程度
- 对异常值有一定鲁棒性,适合常规分布数据。
RS_quantiles根据分位数生成范围:
[ Q(rs), Q(1-rs) ]。
- 非参数方法,适合分布不均的数据
- 有效减少异常值的影响(如 5%-95% 分位数)。
RS_optim基于优化误差动态调整范围。- 重建精度要求高的场景
- 适合对误差敏感的任务,可能效率较低,但结果更精确。
  • rs 是范围缩放因子(Range Scale)。rs是用户定义的参数,根据具体场景和需求选择合格的值。
  • mean:向量分量的平均值(Mean)。
  • std:向量分量的标准差。
参数含义作用
rs范围缩放因子,控制范围的扩展程度。调节范围宽度。rs 越大,范围越宽,适合分布离散的情况;rs 越小,范围越窄,适合分布集中的情况。
mean均值,表示数据的集中趋势。用作范围的中心值,减少偏移误差。
std标准差,表示数据的离散程度。用于计算范围宽度,离散程度越大,生成的范围越宽。

ScalarQuantizer

用于将浮点转化为相对应的量化结果
头文件C语言内容:

#ifndef SCALAR_QUANTIZER_H
#define SCALAR_QUANTIZER_H#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>/* Quantizer 类型枚举 */
typedef enum {QT_8bit,            /* 8 位每分量 */QT_4bit,            /* 4 位每分量 */QT_8bit_uniform,    /* 每分量 8 位,范围统一 */QT_4bit_uniform,    /* 每分量 4 位,范围统一 */QT_fp16,            /* 16 位浮点 */QT_bf16,            /* 16 位 bfloat */QT_8bit_direct,     /* 无需额外计算的直接 8 位编码 */QT_8bit_direct_signed, /* 带符号的直接 8 位编码 */QT_6bit             /* 每分量 6 位 */
} QuantizerType;/* ScalarQuantizer 数据结构 */
typedef struct {size_t d;            /* 输入向量的维度 */size_t code_size;    /* 每个向量的编码大小(字节数) */int bits;            /* 每分量的位数 */QuantizerType qtype; /* 量化器类型 */
} ScalarQuantizer;/* 初始化函数 */
void ScalarQuantizer_init(ScalarQuantizer* sq, size_t d, QuantizerType qtype);/* 设置 derived sizes */
void ScalarQuantizer_set_derived_sizes(ScalarQuantizer* sq);/* 打印量化器信息 */
void ScalarQuantizer_print_info(const ScalarQuantizer* sq);#endif /* SCALAR_QUANTIZER_H */

实现部分:

#include "ScalarQuantizer.h"/* 初始化 ScalarQuantizer */
void ScalarQuantizer_init(ScalarQuantizer* sq, size_t d, QuantizerType qtype) {if (sq == NULL) {fprintf(stderr, "Error: ScalarQuantizer pointer is NULL.\n");exit(EXIT_FAILURE);}sq->d = d;sq->qtype = qtype;sq->code_size = 0; /* 初始化为 0 */sq->bits = 0;      /* 初始化为 0 */ScalarQuantizer_set_derived_sizes(sq);
}/* 设置 code_size 和 bits */
void ScalarQuantizer_set_derived_sizes(ScalarQuantizer* sq) {if (sq == NULL) {fprintf(stderr, "Error: ScalarQuantizer pointer is NULL.\n");exit(EXIT_FAILURE);}switch (sq->qtype) {case QT_8bit:case QT_8bit_uniform:case QT_8bit_direct:case QT_8bit_direct_signed:sq->code_size = sq->d;sq->bits = 8;break;case QT_4bit:case QT_4bit_uniform:sq->code_size = (sq->d + 1) / 2; /* 每两个分量占 1 字节 */sq->bits = 4;break;case QT_6bit:sq->code_size = (sq->d * 6 + 7) / 8; /* 位对齐处理 */sq->bits = 6;break;case QT_fp16:case QT_bf16:sq->code_size = sq->d * 2; /* 每分量 2 字节 */sq->bits = 16;break;default:fprintf(stderr, "Error: Unsupported QuantizerType.\n");exit(EXIT_FAILURE);}/* 检查初始化结果 */if (sq->code_size == 0 || sq->bits == 0) {fprintf(stderr, "Error: Invalid derived sizes.\n");exit(EXIT_FAILURE);}
}/* 打印 ScalarQuantizer 信息 */
void ScalarQuantizer_print_info(const ScalarQuantizer* sq) {if (sq == NULL) {fprintf(stderr, "Error: ScalarQuantizer pointer is NULL.\n");return;}printf("ScalarQuantizer Info:\n");printf("  Dimension (d): %zu\n", sq->d);printf("  Code Size (bytes per vector): %zu\n", sq->code_size);printf("  Bits per component: %d\n", sq->bits);printf("  Quantizer Type: %d\n", sq->qtype);
}

关键点说明

  1. ScalarQuantizer 数据结构:
  • 包含 d(维度)、code_size(编码大小)、bits(每分量位数)和 qtype(量化器类型)。
  1. 初始化函数:
  • ScalarQuantizer_init 接收维度和量化器类型作为输入,并调用 ScalarQuantizer_set_derived_sizes 设置计算派生值。
  1. 错误处理:
  • 添加了对空指针的检查以及对非法 QuantizerType 的错误处理。
  1. 位对齐逻辑:
  • 在 QT_6bit 和 QT_4bit 的计算中,处理了位对齐问题。

train、compute_codes和decode

上述函数的作用参考上一篇链接:标量量化
这里我定义的ScalarQuantizer结构体内容如下:

typedef struct ScalarQuantizer{size_t d;              /* 输入向量的维度 */size_t code_size;      /* 每个向量的编码大小(字节数) */int bits;              /* 每分量的位数 */QuantizerType qtype;   /* 量化器类型 *//* 训练参数 */float rangestat;       /* 范围统计参数 */float rangestat_arg;   /* 范围统计扩展参数 */int n_centroids;       /* 聚类中心数量 *//* 训练结果 */float* trained;        /* 存储训练的量化中心 */float* centroids;      /* 非均匀量化时的聚类中心 *//* 并行和状态跟踪 */int num_threads;       /* 并行计算的线程数量 */size_t progress;       /* 当前训练/编码的进度 *//* 高级量化支持 */int* per_dim_bits;     /* 每维分量的位数,支持动态调整 */float* residuals;      /* 残差向量存储 */int residual_levels;   /* 残差量化层数 */
} ScalarQuantizer;

然后将训练train分为3个部分:ScalarQuantizer_train(QT类4、6、8位)、train_Uniform(均匀量化训练 )和train_NonUniform(非均匀量化训练),其中train_Uniform和train_NonUniform在代码中呈现。

void ScalarQuantizer::train(size_t n, const float* x) {int bit_per_dim = qtype == QT_4bit_uniform ? 4: qtype == QT_4bit                 ? 4: qtype == QT_6bit                 ? 6: qtype == QT_8bit_uniform         ? 8: qtype == QT_8bit                 ? 8: -1;switch (qtype) {case QT_4bit_uniform:case QT_8bit_uniform:train_Uniform(rangestat,rangestat_arg,n * d,1 << bit_per_dim,x,trained);break;case QT_4bit:case QT_8bit:case QT_6bit:train_NonUniform(rangestat,rangestat_arg,n,d,1 << bit_per_dim,x,trained);break;case QT_fp16:case QT_8bit_direct:case QT_bf16:case QT_8bit_direct_signed:// no training necessarybreak;}
}

相关文章:

faiss库中ivf-sq(ScalarQuantizer,标量量化)代码解读-2

文件ScalarQuantizer.h 主要介绍这里面的枚举以及一些函数内容&#xff1a;QuantizerType、RangeStat、ScalarQuantizer、train、compute_codes、decode、SQuantizer、FlatCodesDistanceComputer、get_distance_computer、select_InvertedListScanner QuantizerType 量化类型…...

性能测试工具Grafana、InfluxDB和Collectd的搭建

一、性能监控组成简介 1、监控能力分工:这个系统组合能够覆盖从数据采集、存储到可视化的整个监控流程。Collectd可以收集各种系统和应用的性能指标,InfluxDB提供高效的时序数据存储,而 Grafana 则将这些数据以直观的方式呈现出来。2,实时性能监控:对于需要实时了解系统状…...

【ruby on rails】dup、deep_dup、clone的区别

一、区别 dup 浅复制&#xff1a;dup 方法创建对象的浅复制。 不复制冻结状态&#xff1a;dup 不会复制对象的冻结状态。 不复制单例方法&#xff1a;dup 不会复制对象的单例方法。 deep_dup 深复制&#xff1a;deep_dup 方法创建对象的深复制&#xff0c;递归复制嵌套的对象。…...

原生微信小程序画表格

wxml部分&#xff1a; <view class"table__scroll__view"><view class"table__header"><view class"table__header__item" wx:for"{{TableHeadtitle}}" wx:key"index">{{item.title}}</view></…...

Python实现IP代理池

文章目录 Python实现IP代理池一、引言二、步骤一&#xff1a;获取代理IP1、第一步&#xff1a;爬取代理IP2、第二步&#xff1a;验证代理IP的有效性 三、步骤二&#xff1a;构建IP代理池四、使用示例1、完整的使用示例2、注意事项3、处理网络问题 五、总结 Python实现IP代理池 …...

互联网直播/点播EasyDSS视频推拉流平台视频点播有哪些技术特点?

在数字化时代&#xff0c;视频点播应用已经成为我们生活中不可或缺的一部分。监控技术与视频点播的结合正悄然改变着我们获取和享受媒体内容的方式。这一变革不仅体现在技术层面的进步&#xff0c;更深刻地影响了我们。 EasyDSS视频直播点播平台是一款高性能流媒体服务软件。E…...

32.4 prometheus存储磁盘数据结构和存储参数

本节重点介绍 : prometheus存储磁盘数据结构介绍 indexchunkshead chunksTombstoneswal prometheus对block进行定时压实 compactprometheus 查看支持的存储参数 prometheus存储示意图 内存和disk之间的纽带 wal WAL目录中包含了多个连续编号的且大小为128M的文件&#xff0c…...

C7.【C++ Cont】范围for的使用和auto关键字

目录 1.知识回顾 2.范围for 格式 使用 运行结果 运行过程 范围for的本意 作用 注意 3.底层分析范围for的执行过程 反汇编代码 分析 4.auto关键字 格式 基本用法 在范围for中使用auto 1.知识回顾 for循环的使用参见25.【C语言】循环结构之for文章 2.范围for C…...

联通云服务器部署老项目tomcat记录

1.先在服务器上安装mysql和tomcat 2.tomcat修改端口 3.在联通云运控平台配置tomcat访问端口&#xff08;相当于向外部提供可访问端口&#xff09; 4.将tomcat项目放在服务器tomcat的webapps里面 5.在mysql里创建项目数据库&#xff0c;运行sql创建表和导入数据 6.在配置文…...

剪映自动批量替换视频、图片素材教程,视频批量复刻、混剪裂变等功能介绍

一、三种批量替换模式的区别 二、混剪裂变替换素材 三、分区混剪裂变替换素材 四、按组精确替换素材 五、绿色按钮教程 &#xff08;一&#xff09;如何附加音频和srt字幕 &#xff08;二&#xff09;如何替换固定文本的内容和样式 &#xff08;三&#xff09;如何附加…...

el-dialog中调用resetFields()方法重置表单报错

前言 在开发中&#xff0c;弹框和表单是两个常见的组件&#xff0c;它们通常一起使用以实现用户交互和数据输入。然而&#xff0c;当我们尝试在弹框中调用表单的 resetFields() 方法时&#xff0c;有时会遇到报错的情况。 一、用法错误 确保 this.$refs[ruleForm].resetFields…...

分布式系统接口,如何避免重复提交

分布式系统接口&#xff0c;如何避免重复提交 1、基于Token的幂等设计原理实现步骤技术选型 2、基于Token的幂等设计原理实现步骤适用场景 3、幂等性设计原理实现方式 4、分布式锁原理实现方式适用场景 5、请求去重原理实现方式 6.前端防护原理实现方式适用场景 7.延迟队列原理…...

AI 声音:数字音频、语音识别、TTS 简介与使用示例

在现代 AI 技术的推动下&#xff0c;声音处理领域取得了巨大进展。从语音识别&#xff08;ASR&#xff09;到文本转语音&#xff08;TTS&#xff09;&#xff0c;再到个性化声音克隆&#xff0c;这些技术已经深入到我们的日常生活中&#xff1a;语音助手、自动字幕生成、语音导…...

【论文速读】| 人工智能驱动的网络威胁情报自动化

基本信息 原文标题&#xff1a;AI-Driven Cyber Threat Intelligence Automation 原文作者&#xff1a;Shrit Shah, Fatemeh Khoda Parast 作者单位&#xff1a;加拿大圭尔夫大学计算机科学学院 关键词&#xff1a;网络威胁情报&#xff0c;AI自动化&#xff0c;攻击技术和…...

什么是域名监控?

域名监控是持续跟踪全球域名系统&#xff08;DNS&#xff09;中变化以发现恶意活动迹象的过程。组织可以对其拥有的域名进行监控&#xff0c;以判断是否有威胁行为者试图入侵其网络。他们还可以对客户的域名使用这种技术以执行类似的检查。 你可以将域名监控比作跟踪与自己实物…...

vue3 发送 axios 请求时没有接受到响应数据

<script setup> import Edit from ./components/Edit.vue import axios from axios import { onMounted,ref } from vue// TODO: 列表渲染 //装数据的列表 const list ref([]) const count ref(0) const getList async () > {//通过发送 /list 请求从后端拿到列表数…...

前端使用fontfaceobserver库实现字体设置

要使用FontFaceObserver来加载设置项目本地的字体&#xff0c;先确保字体文件位于项目中或者可以从服务端获取到&#xff0c;这样就可以使用FontFaceObserver来检测并加载这些字体 主要有以下几步&#xff1a; npm或者yarn安装引入fontfaceobserver字体资源引入和font-face配置…...

【人工智能】Python常用库-PyTorch常用方法教程

PyTorch 是一个强大的开源深度学习框架&#xff0c;以其灵活性和动态计算图而广受欢迎。以下是 PyTorch 的详细教程&#xff0c;涵盖从基础到实际应用的使用方法。 1. 安装与导入 1.1 安装 PyTorch 访问 PyTorch 官方网站&#xff0c;根据系统、Python 版本和 CUDA 支持选择安…...

Android Studio安装TalkX AI编程助手

文章目录 TalkX简介编程场景 TalkX安装TalkX编程使用ai编程助手相关文章 TalkX简介 TalkX是一款将OpenAI的GPT 3.5/4模型集成到IDE的AI编程插件。它免费提供特定场景的AI编程指导&#xff0c;帮助开发人员提高工作效率约38%&#xff0c;甚至在解决编程问题的效率上提升超过2倍…...

#渗透测试#红蓝攻防#HW#漏洞挖掘#漏洞复现02-永恒之蓝漏洞

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...

轻量级Docker管理工具Docker Switchboard

简介 什么是 Docker Switchboard &#xff1f; Docker Switchboard 是一个轻量级的 Web 应用程序&#xff0c;用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器&#xff0c;使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...

【Ftrace 专栏】Ftrace 参考博文

ftrace、perf、bcc、bpftrace、ply、simple_perf的使用Ftrace 基本用法Linux 利用 ftrace 分析内核调用如何利用ftrace精确跟踪特定进程调度信息使用 ftrace 进行追踪延迟Linux-培训笔记-ftracehttps://www.kernel.org/doc/html/v4.18/trace/events.htmlhttps://blog.csdn.net/…...

Copilot for Xcode (iOS的 AI辅助编程)

Copilot for Xcode 简介Copilot下载与安装 体验环境要求下载最新的安装包安装登录系统权限设置 AI辅助编程生成注释代码补全简单需求代码生成辅助编程行间代码生成注释联想 代码生成 总结 简介 尝试使用了Copilot&#xff0c;它能根据上下文补全代码&#xff0c;快速生成常用…...