自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

大模型向量去重的N種解決方案!

人工智能
向量數(shù)據(jù)庫去重一定是生產(chǎn)環(huán)境要做的事,它的解決方案也有很多,通常我們會選擇一種高效、且沒有線程安全的解決方案,例如 Redis SetNX 或 Set 數(shù)據(jù)結(jié)構(gòu)來解決。
簡單來說,“向量”Vector 是大模型(LLM)在搜索時使用的一種“技術(shù)手段”,通過向量比對,大模型能找出問題的相關(guān)答案,并且進行智能回答。

向量簡介

Vector 是向量或矢量的意思,向量是數(shù)學(xué)里的概念,而矢量是物理里的概念,但二者描述的是同一件事。

定義:向量是用于表示具有大小和方向的量。

向量可以在不同的維度空間中定義,最常見的是二維和三維空間中的向量,但理論上也可以有更高維的向量。例如,在二維平面上的一個向量可以寫作 (x,y),這里 x 和 y 分別表示該向量沿兩個坐標(biāo)軸方向上的分量;而在三維空間里,則會有一個額外的 z 坐標(biāo),即 (x,y,z)。

例如,有以下 4 種狗,我們要在大模型中如何表示它們呢:

圖片圖片

我們就可以使用向量來表示,如下圖所示:

圖片圖片

向量關(guān)系圖:

圖片圖片

向量數(shù)據(jù)庫

定義:向量數(shù)據(jù)庫是一種專門用于存儲、管理和檢索向量數(shù)據(jù)(即高維數(shù)值數(shù)組)的數(shù)據(jù)庫系統(tǒng)。其核心功能是通過高效的索引結(jié)構(gòu)和相似性計算算法,支持大規(guī)模向量數(shù)據(jù)的快速查詢與分析。

向量數(shù)據(jù)庫以向量為基本存儲單元,這些向量通常由文本、圖像、音頻等非結(jié)構(gòu)化數(shù)據(jù)通過深度學(xué)習(xí)模型(如 Embedding 技術(shù))轉(zhuǎn)換而來,每個向量代表對象在多維空間中的特征。例如,一段文本可轉(zhuǎn)化為 512 維的浮點數(shù)向量,用于表示其語義信息。

向量數(shù)據(jù)庫維度越高,查詢精準(zhǔn)度也越高,查詢效果也越好。

常用向量數(shù)據(jù)庫

Java 領(lǐng)域常用的向量數(shù)據(jù)庫有:

  • Redis Stack:原有 Redis 服務(wù)升級之后就可以用來存儲向量數(shù)據(jù)。
  • Elastic Search
  • Milvus:一款開源的高性能向量數(shù)據(jù)庫,專為存儲、索引和檢索大規(guī)模向量數(shù)據(jù)而設(shè)計。它可以實現(xiàn)萬億級向量的毫秒級相似性搜索。

向量數(shù)據(jù)去重

向量數(shù)據(jù)庫去重通常是在添加時進行判斷,它主要實現(xiàn)方式有以下幾種:

  • 基于向量相似度去重。
  • 基于 Redis 唯一鍵去重。
  • 使用 Redis SetNX 去重。
  • 基于 Redis Set 數(shù)據(jù)結(jié)構(gòu)去重。

具體實現(xiàn)如下。

1.基于向量相似度去重

原理:在插入前計算新向量與已有向量的余弦相似度,若超過閾值(如 0.95)則視為重復(fù)。

EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
    .queryEmbedding(newEmbedding)
    .maxResults(1)
    .minScore(0.95) // 相似度閾值
    .build();
List<EmbeddingMatch<TextSegment>> matches = embeddingStore.search(request);
if (matches.isEmpty()) {
    embeddingStore.add(newEmbedding, textSegment);
}

優(yōu)點:語義級去重,適合文本內(nèi)容相似但表述不同的場景。

缺點:存在線程安全問題,多任務(wù)同時執(zhí)行,可能導(dǎo)致插入重復(fù)數(shù)據(jù)。

2.基于 Redis 唯一鍵去重

原理:使用文本內(nèi)容的哈希值(如 MD5)作為 Redis Key 的一部分,確保唯一性。

String textHash = DigestUtils.md5Hex(textSegment.text());
String redisKey = "embedding:" + textHash;
if (!redisTemplate.hasKey(redisKey)) {
    embeddingStore.add(newEmbedding, textSegment);
    redisTemplate.opsForValue().set(redisKey, "1");
}

優(yōu)點:性能高,適合完全相同的文本內(nèi)容。

缺點:存在線程安全問題,多任務(wù)同時執(zhí)行,可能導(dǎo)致插入重復(fù)數(shù)據(jù)。

3.使用 Redis SetNX 去重

原理:使用 Redis 的 SETNX(set if not exists)命令,避免非原子性問題,它是先判斷才插入,如果已經(jīng)存在就不再插入了。

具體實現(xiàn)代碼如下:

// 生成文本的唯一哈希(如 MD5)
String textHash = DigestUtils.md5Hex(textSegment.text());
String redisKey = "vector:" + textHash;
// 判斷是否存在
Boolean isSet = redisTemplate.opsForValue()
    .setIfAbsent(redisKey, "1");
if (Boolean.TRUE.equals(isSet)) {
    // 鍵不存在,保存向量數(shù)據(jù)
    embeddingStore.add(embedding, textSegment);
} else {
    // 鍵已存在,跳過或報錯
    throw new RuntimeException("重復(fù)數(shù)據(jù)");
}

優(yōu)點:性能高,不存在線程安全問題。

4.基于 Redis Set 數(shù)據(jù)結(jié)構(gòu)去重

原理:Set 去重,將向量 ID 或文本哈希存入 Redis Set,插入前檢查是否存在。

// 生成文本的唯一哈希(如 MD5)
String textHash = DigestUtils.md5Hex(textSegment.text());
if (redisTemplate.opsForSet().add("unique_embeddings", textHash) == 1) {
    embeddingStore.add(newEmbedding, textSegment);
}

優(yōu)點:簡單高效,不存在線程安全問題。

缺點:需維護額外的 Set 數(shù)據(jù)結(jié)構(gòu)。

小結(jié)

向量數(shù)據(jù)庫去重一定是生產(chǎn)環(huán)境要做的事,它的解決方案也有很多,通常我們會選擇一種高效、且沒有線程安全的解決方案,例如 Redis SetNX 或 Set 數(shù)據(jù)結(jié)構(gòu)來解決。


責(zé)任編輯:武曉燕 來源: 磊哥和Java
相關(guān)推薦

2022-02-18 09:20:43

消息中間件分布式MQ 冪等

2021-08-04 17:40:42

代碼Java消息冪等

2024-07-12 11:35:20

2020-09-09 08:23:53

URLIP代碼

2023-05-16 13:07:57

GPT4ALL語言模型

2012-05-30 15:40:16

大并發(fā)并發(fā)解決方案

2023-05-19 13:58:12

2019-02-12 05:34:25

2023-09-07 13:25:09

2018-05-04 07:36:35

醫(yī)療行業(yè)物聯(lián)網(wǎng)IoT

2010-01-12 12:15:25

SOA安全解決方案

2021-09-26 09:17:01

Python命令定時任務(wù)

2023-04-14 14:54:29

2009-03-25 15:55:22

2022-10-27 18:00:01

品質(zhì)寬帶

2020-11-11 16:30:55

微軟Windows 10Windows

2023-10-30 08:00:00

區(qū)塊鏈去中心化

2024-09-19 08:11:28

2017-12-26 14:05:21

潤乾大屏可視化

2016-07-25 16:20:18

點贊
收藏

51CTO技術(shù)棧公眾號