Docs 菜单
Docs 主页
/

灵活的维度和量化

Voyage AI嵌入模型支持灵活的维度和量化,可帮助您优化基于向量的应用程序的存储和搜索成本。本页介绍如何使用这些功能来降低成本,同时保持较高的检索质量。

通过 Google Colab 中的交互式教程了解灵活的维度和量化。

在使用大规模向量搜索应用程序时,例如跨海量存储库的代码检索,存储和计算成本可能会很高。这些成本与以下因素扩展线性关系:

  • 嵌入维数:每个向量的维数

  • 精度:用于对向量中每个数字进行编码的位数

通过减少其中一个或两个因素,您可以大幅降低成本,而不会显着影响检索质量。 Voyage AI模型支持两种互补的技术来实现这一目标:

  • 俄罗斯套娃嵌入:允许您通过截断到更少的维度来使用较小版本的嵌入

  • 量化:将嵌入中每个数字的精度从32 位浮点数降低为较低精度的格式

这些技术是通过套娃学习和量化感知培训启用的,训练模型即使在维度或量化值减少的情况下也能保持质量。

俄罗斯套娃嵌入是一种特殊类型的向量嵌入,其中包含嵌套在单个向量中的多个不同大小的有效嵌入。这样,您就可以灵活选择最能平衡性能和费用要求的维度。

最新的 Voyage 嵌入模型可生成 Matryoshka 嵌入,并直接通过output_dimension 参数支持多个输出维度。要学习;了解详情,请参阅 模型概述。

通过套娃学习,单个嵌入包含不同长度的嵌套嵌入族。示例,一个 2048 维的 Voyage 嵌入包含多个较短长度的有效嵌入:

  • 前 256 维形成有效的 256 维嵌入

  • 前 512 维形成有效的 512 维嵌入

  • 前 1024 维形成有效的 1024 维嵌入

  • 所有 2048 维度构成全保真嵌入

每个较短版本提供的检索质量略低于完整嵌入,但需要的存储和计算资源较少。

通过保留维度的前导子集来截断套娃嵌入。以下示例演示了如何将 1024 维向量截断为 256 维度:

import voyageai
import numpy as np
def embd_normalize(v: np.ndarray) -> np.ndarray:
# Normalize rows of a 2D array to unit vectors
row_norms = np.linalg.norm(v, axis=1, keepdims=True)
if np.any(row_norms == 0):
raise ValueError("Cannot normalize rows with a norm of zero.")
return v / row_norms
vo = voyageai.Client()
# Generate 1024-dimensional embeddings
embd = vo.embed(['Sample text 1', 'Sample text 2'], model='voyage-4-large').embeddings
# Truncate to 256 dimensions and normalize
short_dim = 256
resized_embd = embd_normalize(np.array(embd)[:, :short_dim]).tolist()

量化通过将高精度浮点数转换为较低精度格式来降低嵌入的精度。此进程可大幅降低存储和计算成本,同时保持较高的检索质量。

最新的 Voyage 嵌入模型使用量化感知培训进行训练,这意味着即使在量化时,它们也能保持较高的检索质量。要学习;了解更多信息,请参阅模型概述。

注意

许多支持向量存储和检索的数据库也支持量化嵌入,包括MongoDB。要学习;了解有关MongoDB Vector Search 中的量化的更多信息,请参阅向量量化。

量化使用比标准 32 位浮点格式更少的位数来表示每个维度,从而降低了嵌入的精度。量化嵌入不是每个维度使用 4 个字节,而是使用:

  • 8位整数(每个维度1 字节):将存储减少4 倍

  • 二进制(每个维度1 位):将存储减少 倍32

尽管大小大幅减小,但像 Voyage 这样经过量化感知训练的模型仍能保持较高的检索质量。支持的 Voyage 模型通过使用 output_dtype 参数指定输出数据类型启用量化:

数据类型
说明

float

每个返回的嵌入都是一个32 位(4 字节)单精度浮点数的列表。这是默认,可提供最高的精度和检索准确度。

int8uint8

每个返回的嵌入都是一个 8 位(1 字节)整数的列表,范围分别从 -128 到 127 和 0 到 255。

binaryubinary

每个返回的嵌入都是一个8 位整数的列表,这些整数表示位封装的量化单位嵌入值:int8 binaryuint8代表ubinary , 代表 。返回的整数列表的长度是嵌入的实际维度的1 /8binary 类型使用偏移二进制方法,如下所述。

例子

了解二进制量化

  1. 考虑以下嵌入值:

    -0.0396, 0.0062, -0.0745, -0.0390, 0.0046, 0.0003, -0.0850, 0.0399
  2. 二进制量化使用以下规则将每个值转换为单个位:

    • 小于 0 的值将转换为 0

    • 大于或等于 0 的值将转换为 1

    0, 1, 0, 0, 1, 1, 0, 1
  3. 这八个位打包成一个 8 位整数:01001101。此整数转换为十进制形式的 77

  4. 要转换为最终输出类型,应用以下转换:

    输出类型
    转换方法
    结果

    ubinary

    uint8:直接使用该值作为无符号整数。

    77

    binary

    int8:通过减去 128来应用偏移量二进制方法。

    -51 (等于 77 - 128

偏移二进制是一种以二进制形式表示有符号整数的方法。 Voyage AI将此方法用于 输出类型,以将位压缩二进制嵌入编码为有符号整数binary int8()。

偏移二进制方法的工作原理是加上或减去偏移值:

  • 转换为二进制时:在编码前将 添加到有符号整数128

  • 从二进制转换时:解码后从整数中减去128

对于 8 位有符号整数(范围为 -128127),偏移量始终为 128

例子

有符号整数转二进制

要将 -32 表示为 8 位二进制数:

  1. 将偏移量 (128) 添加到 -32,得到 96

  2. 96 转换为二进制:01100000

例子

二进制到有符号整数

要从 8 位二进制数 01010101 确定带符号整数:

  1. 直接将其转换为整数:85

  2. 85 中减去偏移量 (128),得到 -43

您可以手动将浮点嵌入转换为二进制格式,或将二进制嵌入解压缩回单个位。以下示例演示了这两种操作:

import numpy as np
import voyageai
vo = voyageai.Client()
# Generate float embeddings
embd_float = vo.embed('Sample text 1', model='voyage-4-large', output_dimension=2048).embeddings[0]
# Compute 512-dimensional bit-packed binary and ubinary embeddings from 2048-dimensional float embeddings
embd_binary_calc = (np.packbits(np.array(embd_float) > 0, axis=0) - 128).astype(np.int8).tolist() # Quantize, binary offset
embd_binary_512_calc = embd_binary_calc[0:64] # Truncate. Binary is 1/8 length of embedding dimension.
embd_ubinary_calc = (np.packbits(np.array(embd_float) > 0, axis=0)).astype(np.uint8).tolist() # Quantize, binary offset
embd_ubinary_512_calc = embd_ubinary_calc[0:64] # Truncate. Binary is 1/8 length of embedding dimension.
import numpy as np
import voyageai
vo = voyageai.Client()
# Generate binary embeddings
embd_binary = vo.embed('Sample text 1', model='voyage-4-large', output_dtype='binary', output_dimension=2048).embeddings[0]
embd_ubinary = vo.embed('Sample text 1', model='voyage-4-large', output_dtype='ubinary', output_dimension=2048).embeddings[0]
# Unpack bits
embd_binary_bits = [format(x, f'08b') for x in np.array(embd_binary) + 128] # List of (bits) strings
embd_binary_unpacked = [bit == '1' for bit in ''.join(embd_binary_bits)] # List of booleans
embd_ubinary_bits = [format(x, f'08b') for x in np.array(embd_ubinary)] # List of (bits) strings
embd_ubinary_unpacked = [bit == '1' for bit in ''.join(embd_ubinary_bits)] # List of booleans

后退

分词器

在此页面上