Path: blob/main/extensions/copilot/src/platform/embeddings/common/embeddingsStorage.ts
13401 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Embedding, EmbeddingType, getWellKnownEmbeddingTypeInfo } from './embeddingsComputer';67/**8* Packs the embedding into a binary value for efficient storage.9*/10export function packEmbedding(embedding: Embedding): Uint8Array {11const embeddingMetadata = getWellKnownEmbeddingTypeInfo(embedding.type);12if (embeddingMetadata?.quantization.document === 'binary') {13// Generate packed binary14if (embedding.value.length % 8 !== 0) {15throw new Error(`Embedding value length must be a multiple of 8 for ${embedding.type.id}, got ${embedding.value.length}`);16}1718const data = new Uint8Array(embedding.value.length / 8);19for (let i = 0; i < embedding.value.length; i += 8) {20let value = 0;21for (let j = 0; j < 8; j++) {22value |= (embedding.value[i + j] >= 0 ? 1 : 0) << j;23}24data[i / 8] = value;25}26return data;27}2829// All other formats default to float32 for now30const data = Float32Array.from(embedding.value);31return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);32}3334/**35* Unpacks an embedding from a binary value packed with {@link packEmbedding}.36*/37export function unpackEmbedding(type: EmbeddingType, data: Uint8Array): Embedding {38const embeddingMetadata = getWellKnownEmbeddingTypeInfo(type);39if (embeddingMetadata?.quantization.document === 'binary') {40// Old metis versions may have stored the values as a float3241if (!(type.equals(EmbeddingType.metis_1024_I16_Binary) && data.length >= 1024)) {42const values = new Array(data.length * 8);43for (let i = 0; i < data.length; i++) {44const byte = data[i];45for (let j = 0; j < 8; j++) {46values[i * 8 + j] = (byte & (1 << j)) > 0 ? 0.03125 : -0.03125;47}48}49return { type, value: values };50}51}5253const float32Array = new Float32Array(data.buffer, data.byteOffset, data.byteLength / 4);54return { type, value: Array.from(float32Array) };55}565758