小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

干貨 | Elasticsearch 向量搜索的工程化實(shí)戰(zhàn)

 銘毅天下 2021-12-24

1、背景

作為一家搜索引擎公司,我們會(huì)很倚賴 ES 幫忙處理包括文章召回,數(shù)據(jù)源劃分,實(shí)體、標(biāo)簽管理等任務(wù),而且都收到了不錯(cuò)的結(jié)果。

最近我們需要對(duì)行業(yè)知識(shí)庫(kù)進(jìn)行建模,其中可能會(huì)涉及到實(shí)體匹配、模糊搜索、向量搜索等多種召回和算分方式,最終我們選擇了通過(guò) ES 7.X (最終選擇 7.10)里的新功能,Dense vector 幫忙一起完成這部分的需求。

2、技術(shù)選型

2.1 解決方案需求

  1. 支持向量搜索
  2. 支持多維度篩選、過(guò)濾
  3. 吞吐速率
  4. 學(xué)習(xí)、使用成本
  5. 運(yùn)維成本

2.2 使用場(chǎng)景設(shè)計(jì)

  1. 離線數(shù)據(jù)準(zhǔn)備
    1. 在離線數(shù)據(jù)構(gòu)建完成后,存入該引擎
    2. 引擎對(duì)數(shù)據(jù)中各字段進(jìn)行索引
  2. 在線數(shù)據(jù)召回
    1. 根據(jù) query 理解結(jié)果構(gòu)建的 query 語(yǔ)句進(jìn)行數(shù)據(jù)召回
    2. 對(duì)結(jié)果進(jìn)行一定的篩選
    3. 對(duì)結(jié)果進(jìn)行一定的打分排序

2.3 數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)

在確定了數(shù)據(jù)的使用場(chǎng)景我們確定了數(shù)據(jù)結(jié)構(gòu)中,大致會(huì)包含以下一些字段

  1. 唯一 id:用以做知識(shí)的去重和快速獲取
  2. 實(shí)體、屬性、取值:用來(lái)描述知識(shí)的具體內(nèi)容
  3. 置信度:用來(lái)描述知識(shí)的可信度
  4. 分類 flag:知識(shí)主要分類及推薦 category 等
  5. 向量表示:作為知識(shí)相似性、相關(guān)性召回、打分的依據(jù)
  6. ref 信息:用來(lái)回溯解析/獲取該知識(shí)的源信息
  7. 其他屬性:包括生效、刪除、修改時(shí)間等支持性的通用屬性

2.4 解決方案對(duì)比

為了能支持上述的使用需求,我們對(duì)比了包括 ES、Faiss 等多種解決方案。其中,FaissSPTAG 只是核心算法庫(kù),需要進(jìn)行二次開(kāi)發(fā)包裝成服務(wù);Milvus1.x 版本中只能存儲(chǔ) id向量,不能完整的滿足我們的使用需求;基于集群穩(wěn)定性和可維護(hù)性等考慮,相對(duì)于后置插件的部署,我們更傾向于使用 ES 的原生功能,所以選擇 ES 的原生向量搜索功能作為我們的最終選擇。

對(duì)比參考:

種類實(shí)現(xiàn)語(yǔ)言客戶端支持多條件召回學(xué)習(xí)成本引入成本運(yùn)維成本分布式性能社區(qū)備注
ElasticsearchJavaJava/Pythonyesyes活躍原生功能
FaissPythonPythonnono一般需要二次開(kāi)發(fā)
MilvusPython + GoLangPython/Java/GoLangnono一般1.x 功能不全
OpenDistro Elasticsearch KNNJava + C++Java/Pythonyesyes一般內(nèi)置插件
SPTAGC++Python + C#nono一般需要二次開(kāi)發(fā)

3、數(shù)據(jù)流轉(zhuǎn)流程

3.1 離線數(shù)據(jù)處理部分

  1. 從多數(shù)據(jù)源采集數(shù)據(jù)
  2. 數(shù)據(jù)清洗及預(yù)處理
  3. 通過(guò)算法引擎提取知識(shí)
  4. 通過(guò)算法引擎將知識(shí)轉(zhuǎn)換為向量
  5. 將知識(shí)的基礎(chǔ)信息連同向量數(shù)據(jù)存入 ES

3.2 在線數(shù)據(jù)召回部分

  1. 從前端獲取搜索條件
  2. 通過(guò) query 理解模塊進(jìn)行檢索條件解析
  3. ES 中進(jìn)行搜索
  4. 對(duì)結(jié)果進(jìn)行分?jǐn)?shù)調(diào)整
  5. 返回前端

4、ES 向量搜索的使用示例

4.1 索引設(shè)計(jì)

Settings

{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2,
"index": {
"routing": {
"allocation": {
"require": {
"node_group": "hot" // 1)
}
}
},
"store": {
"preload": [ // 2)
"knowledge",
"category",
"available",
"confidence",
"del",
"kid"
]
},
"search": {
"slowlog": {
"threshold": {
"query": {
"warn": "1s" // 3)
},
"fetch": {
"warn": "1s" // 3)
}
}
}
},
"translog": {
"flush_threshold_size": "512mb", // 4)
"sync_interval": "5m", // 4)
"durability": "async" // 4)
},
"sort": {
"field": [ // 5)
"kid",
"confidence"
],
"order": [ // 5)
"asc",
"desc"
]
}
}
}
}
  • 說(shuō)明:
  1. 由于向量數(shù)據(jù)較大,所以傾向于將整個(gè)索引都放置在硬件性能更好的節(jié)點(diǎn)
  2. 為了支持高性能過(guò)濾,將常用的字段預(yù)先加載在內(nèi)存中
  3. 對(duì)慢查詢開(kāi)啟日志方便后續(xù)性能問(wèn)題的調(diào)查
  4. 知識(shí)庫(kù)的重建是離線的,會(huì)在更新時(shí)進(jìn)行大量寫(xiě)入,所以對(duì) translog 的提交間隔拉長(zhǎng),加快寫(xiě)入速度
  5. 在實(shí)際使用中kid是自增id,同時(shí)可能會(huì)對(duì)知識(shí)的置信度做排序等,所以會(huì)使用 sort field 存儲(chǔ)這兩個(gè)字段

Mapping

{
"mappings": {
"properties": {
"kid": {
"type": "keyword"
},
"knowledge": {
"type": "keyword"
},
"knowledge_phrase": { // 1)
"type": "text",
"analyzer": "faraday"
},
"attribue": { // 1)
"type": "keyword",
"fields": {
"phrase": {
"type": "text",
"analyzer": "faraday"
}
}
},
"value": { // 1)
"type": "keyword",
"fields": {
"phrase": {
"type": "text",
"analyzer": "faraday"
}
}
},
"confidence": { // 2)
"type": "double"
},
"category": {
"type": "keyword"
},
"vector": { // 3)
"type": "dense_vector",
"dims": 512
},
"ref": {
"type": "text",
"index": false
},
"available": {
"type": "keyword"
},
"del": {
"type": "keyword"
},
"create_timestamp": {
"type": "date",
"format": [
"strict_date_hour_minute_second",
"yyyy-MM-dd HH:mm:ss"
]
},
"update_timestamp": {
"type": "date",
"format": [
"strict_date_hour_minute_second",
"yyyy-MM-dd HH:mm:ss"
]
}
}
}
}
  • 說(shuō)明:
  1. 除了對(duì)知識(shí)條目的完整搜索之外,還會(huì)需要進(jìn)行模糊檢索,我們使用了自研的 farady 分詞器對(duì)知識(shí)條目的各部分進(jìn)行了分詞處理
  2. 知識(shí)庫(kù)中的知識(shí)條目會(huì)有一部分進(jìn)行專家/人工審核和維護(hù),所以會(huì)對(duì)不同的條目設(shè)置不同的置信度
  3. 數(shù)據(jù)預(yù)處理之后會(huì)轉(zhuǎn)成 512 位的向量存在這個(gè)字段中

4.2 數(shù)據(jù)流轉(zhuǎn)

  • 離線部分:
  1. 數(shù)據(jù)采集及清洗
  2. 通過(guò) 模型A 從文章中找到知識(shí)條目
  3. 通過(guò) 模型B 將知識(shí)條目轉(zhuǎn)化成向量
    1. 此處 模型A 模型B 為自研模型,運(yùn)用了包括知識(shí)密度計(jì)算等算法以及 bert tersonflow 等框架
  4. 將原文、知識(shí)條目等核心內(nèi)容插入數(shù)據(jù)庫(kù)
  5. 將核心知識(shí)內(nèi)容、向量等組裝成檢索單元插入 ES
  6. 專家團(tuán)隊(duì)會(huì)針對(duì)數(shù)據(jù)庫(kù)中的知識(shí)條目進(jìn)行審核、修改和迭代
  7. 算法團(tuán)隊(duì)會(huì)根據(jù)知識(shí)條目的更新以及其他的標(biāo)注對(duì)數(shù)據(jù)鏈路中的模型進(jìn)行迭代,對(duì)在線知識(shí)庫(kù)進(jìn)行更新
  • 在線部分:
  1. 前端收到請(qǐng)求之后調(diào)用 query 理解 組件進(jìn)行分析
  2. 剔除無(wú)效內(nèi)容之后,找出 query 里的分類信息等意圖之后,構(gòu)建用來(lái)召回的向量和相關(guān)的篩選條件
  3. 通過(guò)組合出來(lái)的 ESquery 條件對(duì)知識(shí)庫(kù)進(jìn)行篩選,并配合置信度等對(duì)結(jié)果進(jìn)行調(diào)整
  4. 對(duì)召回結(jié)果進(jìn)行不同策略的分?jǐn)?shù)調(diào)整和排序,最后輸出給前端

4.3 示例 query

POST knowledge_current_reader/_search
{
"query": {
"script_score": {
"query": {
"bool": {
"filter": [
{
"term": {
"del": 0
}
},
{
"term": {
"available": 1
}
}
],
"must": {
"bool": {
"should": [
{
"term": {
"category": "type_1",
"boost": 10
}
},
{
"term": {
"category": "type_2",
"boost": 5
}
}
]
}
},
"should": [
{
"match_phrase": {
"knowledge_phrase": {
"query": "some_query",
"boost": 10
}
}
},
{
"match": {
"attribute": {
"query": "some_query",
"boost": 5
}
}
},
{
"match": {
"value": {
"query": "some_query",
"boost": 5
}
}
},
{
"term": {
"knowledge": {
"value": "some_query",
"boost": 30
}
}
},
{
"term": {
"attribute": {
"value": "some_query",
"boost": 15
}
}
},
{
"term": {
"value": {
"value": "some_query",
"boost": 10
}
}
}
]
}
},
"script": {
"source": "cosineSimilarity(params.query_vector, 'vector') + sigmoid(1, Math.E, _score) + (1 / Math.log(doc['confidence'].value))",
"params": {
"query_vector": [ ... ]
}
}
}
}
}
  • 說(shuō)明:
  1. 上述 query 的條件、參數(shù)僅做示意,屬于實(shí)際線上使用的脫敏、簡(jiǎn)化版
  2. 計(jì)算公式為迭代中某一版,后續(xù)調(diào)整和升級(jí)并未體現(xiàn)
  3. 邊界條件及空值在輔助服務(wù)和 pipeline 中進(jìn)行處理,簡(jiǎn)化了其中邊界條件處理和判斷部分邏輯

5、遇到的問(wèn)題

5.1 響應(yīng)時(shí)間長(zhǎng)

由于需要進(jìn)行向量計(jì)算,ES 需要耗費(fèi)大量時(shí)間、資源做距離計(jì)算,為此我們進(jìn)行了以下一些優(yōu)化:

  1. 特征值截取小數(shù)位數(shù):
    1. 為了保證特征的表征,我們并沒(méi)有調(diào)整由 bert 框架輸出的向量位數(shù)
    2. 在權(quán)衡了存取效率、數(shù)據(jù)精度和計(jì)算速度之后,我們將每一個(gè) label 的精度由16位截取為5位小數(shù)
    3. 這樣雖然損失了部分精度(約 X%),但是大大降低了存取和計(jì)算時(shí)間(約 Y%
  2. 在進(jìn)行 query 之前預(yù)先對(duì)意圖、可能分類進(jìn)行分析
    1. 為了減少納入計(jì)算排序的數(shù)據(jù),我們會(huì)在 query 組裝之前對(duì)原始 query 內(nèi)容進(jìn)行分析
    2. 配合用戶行為埋點(diǎn)和專家的先驗(yàn)知識(shí),將知識(shí)進(jìn)行大致分類,并對(duì) query 和分類進(jìn)行不同權(quán)重的匹配
    3. 這樣雖然降低了召回率(約 X%),但增加了準(zhǔn)確性(約 Y%),同時(shí)也提高了部分計(jì)算效率(約 Z%
  3. 精簡(jiǎn)計(jì)算公式
    1. 將一部分分?jǐn)?shù)計(jì)算的邏輯外置,盡可能精簡(jiǎn) ES 需要處理的運(yùn)算邏輯
    2. 在召回之后增加多種打分策略,通過(guò)配置進(jìn)行應(yīng)用、權(quán)重調(diào)整等操作
    3. 這樣降低了 ES 的響應(yīng)時(shí)間(約 X%),同時(shí)通過(guò)外置的打分公式調(diào)整,間接的提高了準(zhǔn)確性(約 Y%

5.2 知識(shí)質(zhì)量參差不齊

由于知識(shí)條目是通過(guò)算法進(jìn)行抽取的,而且知識(shí)還會(huì)存在一定的時(shí)效性,可能造成知識(shí)的不準(zhǔn)確等問(wèn)題,為此我們進(jìn)行了以下一些優(yōu)化:

  1. 持續(xù)的算法迭代:
    1. 根據(jù)用戶埋點(diǎn)信息和標(biāo)注信息對(duì)模型進(jìn)行持續(xù)迭代
    2. 選取更加優(yōu)質(zhì)的知識(shí)抽取結(jié)果對(duì)線上數(shù)據(jù)進(jìn)行全量/增量更新
    3. 經(jīng)過(guò) X 批次的迭代,將知識(shí)的正確性從 Y% 提高到了 Z%
  2. 對(duì)模型輸出的知識(shí)進(jìn)行后置處理
    1. 將僅存在部分助詞(如)差異的知識(shí)條目進(jìn)行過(guò)濾、合并
    2. 給部分熱門的知識(shí)條目設(shè)置過(guò)期時(shí)間,并通過(guò)部分人工審核的方式干預(yù)知識(shí)條目的生產(chǎn)
    3. 維護(hù)專家知識(shí)庫(kù)的方式對(duì)可信知識(shí)進(jìn)行標(biāo)記及提權(quán)
    4. 維護(hù)了 X 類目的 Y 條專家知識(shí),同時(shí)經(jīng)過(guò)人工干預(yù)了大概 Z% 的知識(shí)條目,將知識(shí)的正確性從 W% 提高到了 K%

結(jié)論與展望

本文依托我們公司的使用場(chǎng)景,對(duì)圍繞 ES 向量字段(Dense vector)構(gòu)建的一個(gè)系統(tǒng)進(jìn)行了大致描述,同時(shí)對(duì)一些常見(jiàn)問(wèn)題及解決方案進(jìn)行了闡述。

目前該方案支持了我們對(duì)于知識(shí)庫(kù)的相關(guān)搜索功能,相較于之前的純基于實(shí)體識(shí)別和 ngram 匹配的方案整體準(zhǔn)確率和召回率都有將近兩位數(shù)百分比的提升。

未來(lái)我們會(huì)對(duì)整個(gè)系統(tǒng)的響應(yīng)速度、穩(wěn)定性進(jìn)行提升,并對(duì)知識(shí)庫(kù)的構(gòu)建效率以及知識(shí)的準(zhǔn)確性持續(xù)進(jìn)行迭代。

作者介紹

死敵wen,Elastic 認(rèn)證工程師,搜索架構(gòu)師,10年+工作經(jīng)驗(yàn),畢業(yè)于復(fù)旦大學(xué)。

博客:https://blog.csdn.net/weixin_40601534

Github:https://github.com/godlockin

說(shuō)明

上個(gè)月,死磕 Elasticsearch 知識(shí)星球搞了:“群智涌現(xiàn)”杯輸出倒逼輸入——Elastic干貨輸出活動(dòng)。

后續(xù)會(huì)不定期逐步推出系列文章,目的:以文會(huì)友,“輸出倒逼輸入”。

推薦

1、重磅 | 死磕 Elasticsearch 方法論認(rèn)知清單(2021年國(guó)慶更新版)
2Elasticsearch 7.X 進(jìn)階實(shí)戰(zhàn)私訓(xùn)課(口碑不錯(cuò))

短時(shí)間快習(xí)得多干貨!

已帶領(lǐng)77位球友通過(guò) Elastic 官方認(rèn)證!

比同事搶先一步學(xué)習(xí)進(jìn)階干貨

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多