亞馬遜云科技向量數據庫助力生成式AI成功落地實踐探秘(一) ?

隨著大語言模型效果明顯提升,其相關的應用不斷涌現呈現出越來越火爆的趨勢。其中一種比較被廣泛關注的技術路線是大語言模型(LLM)+知識召回(Knowledge Retrieval)的方式,在私域知識問答方面可以很好的彌補通用大語言模型的一些短板,解決通用大語言模型在專業領域回答缺乏依據、存在幻覺等問題。其基本思路是把私域知識文檔進行切片,然后向量化后續通過向量數據庫檢索進行召回,再作為上下文輸入到大語言模型進行歸納總結。

在這個技術方向的具體實踐中,知識庫可以采取基于倒排和基于向量的向量數據庫兩種索引方式進行構建,它對于知識問答流程中的知識召回這步起關鍵作用,和普通的文檔索引或日志索引不同,知識的向量化需要借助深度模型的語義化能力、存在文檔切分、向量數據模型部署&推理等額外步驟。知識向量化建庫即向量數據庫過程中,不僅僅需要考慮原始的文檔量級,還需要考慮切分粒度,向量維度等因素,最終被向量數據庫索引的知識條數可能達到一個非常大的量級,可能由以下兩方面的原因引起:

1.各個行業的既有文檔量很高,如金融、醫藥、法律領域等,新增量也很大。

2.為了召回效果的追求,對文檔的切分常常會采用按句或者按段進行多粒度的冗余存貯。

這些細節對知識向量數據庫的寫入和查詢性能帶來一定的挑戰,為了優化向量化知識庫的構建和管理,本文基于亞馬遜云科技的服務,構建了如下圖的知識庫構建流程:

1.通過 S3 Bucket 的 Handler 實時觸發 Amazon Lambda 啟動對應知識文件入庫的 Amazon Glue job;

2.Glue Job 中會進行文檔解析和拆分,并調用 Amazon Sagemaker 的 Embedding 模型進行向量化;

3.通過 Bulk 方式注入到 Amazon OpenSearch 中去。

并對整個流程中涉及的多個方面,包括如何進行知識向量化、向量數據庫調優總結了一些最佳實踐和心得。

知識向量化(即向量數據庫的原始步驟)的前置步驟是進行知識的拆分,語義完整性的保持是最重要的考量。分兩個方面展開討論。該如何選用以下兩個關注點分別總結了一些經驗:

a. 拆分片段的方法

關于這部分的工作,Langchain 作為一種流行的大語言模型集成框架,提供了非常多的 Document Loader 和 Text Spiltters,其中的一些實現具有借鑒意義,但也有不少實現效果是重復的。

目前使用較多的基礎方式是采用 Langchain 中的 RecursiveCharacterTextSplitter,屬于是 Langchain 的默認拆分器。它采用這個多級分隔字符列表 – [“\n\n”, “\n”, ” “, “”] 來進行拆分,默認先按照段落做拆分,如果拆分結果的 chunk_size 超出,再繼續利用下一級分隔字符繼續拆分,直到滿足 chunk_size 的要求。

但這種做法相對來說還是比較粗糙,還是可能會造成一些關鍵內容會被拆開。對于一些其他的文檔格式可以有一些更細致的做法。

FAQ 文件,必須按照一問一答粒度拆分,后續向量化的輸入可以僅僅使用問題,也可以使用問題+答案(本系列 blog 的后續文章會進一步討論)

Markdown 文件,”#”是用于標識標題的特殊字符,可以采用 MarkdownHeaderTextSplitter 作為分割器,它能更好的保證內容和標題對應的被提取出來。

PDF 文件,會包含更豐富的格式信息。Langchain 里面提供了非常多的 Loader,但 Langchain 中的 PDFMinerPDFasHTMLLoader 的切分效果上會更好,它把 PDF 轉換成 HTML,通過 HTML 的 <div> 塊進行切分,這種方式能保留每個塊的字號信息,從而可以推導出每塊內容的隸屬關系,把一個段落的標題和上一級父標題關聯上,使得信息更加完整。類似下面這種效果。

b. 模型對片段長度的支持

由于拆分的片段后續需要通過向量化模型進行推理,所以必須考慮向量化模型的 Max_seq_length 的限制,超出這個限制可能會導致出現截斷,導致語義不完整。從支持的 Max_seq_length 來劃分,目前主要有兩類 Embedding 模型,如下表所示(這四個是有過實踐經驗的模型)。

這里的 Max_seq_length 是指 Token 數,和字符數并不等價。依據之前的測試經驗,前三個模型一個 token 約為 1.5 個漢字字符左右。而對于大語言模型,如 chatglm,一個 token 一般為 2 個字符左右。如果在切分時不方便計算 token 數,也可以簡單按照這個比例來簡單換算,保證不出現截斷的情況。

前三個模型屬于基于 Bert 的 Embedding 模型,OpenAI 的 text-embedding-ada-002 模型是基于 GPT3 的模型。前者適合句或者短段落的向量化,后者 OpenAI 的 SAAS 化接口,適合長文本的向量化,但不能私有化部署。

可以根據召回效果進行驗證選擇。從目前的實踐經驗上看 text-embedding-ada-002 對于中文的相似性打分排序性可以,但區分度不夠(集中 0.7 左右),不太利于直接通過閾值判斷是否有相似知識召回。

另外,對于長度限制的問題也有另外一種改善方法,可以對拆分的片段進行編號,相鄰的片段編號也臨近,當召回其中一個片段時,可以通過向量數據庫的 range search 把附近的片段也召回回來,也能保證召回內容的語意完整性。

我們上面提到四個向量數據庫模型只是提到了模型對于文本長度的支持差異,效果方面目前并沒有非常權威的結論。可以通過 leaderboard 來了解各個模型的性能,榜上的大多數的模型的評測還是基于公開數據集的 benchmark,對于真實生產中的場景 benchmark 結論是否成立還需要 case by case 地來看。但原則上有以下幾方面的經驗可以分享:

經過垂直領域 Finetune 的模型比原始向量模型有明顯優勢;

目前的向量化模型分為兩類,對稱和非對稱。未進行微調的情況下,對于 FAQ 建議走對稱召回,也就是 Query 到 Question 的召回。對于文檔片段知識,建議使用非對稱召回模型,也就是 Query 到 Answer(文檔片段)的召回;

沒有效果上的明顯的差異的情況下,盡量選擇向量維度短的模型,高維向量(如 openai 的 text-embedding-ada-002)會給向量數據庫造成檢索性能和成本兩方面的壓力。

更多的內容會在本系列的召回優化部分進行深入討論。

真實的業務場景中,文檔的規模在百到百萬這個數量級之間。按照冗余的多級召回方式,對應的知識條目最高可能達到億的規模。由于整個離線計算的規模很大,所以必須并發進行,否則無法滿足知識新增和向量檢索效果迭代的要求。步驟上主要分為以下三個計算階段。

文檔切分并行

計算的并發粒度是文件級別的,處理的文件格式也是多樣的,如 TXT 純文本、Markdown、PDF 等,其對應的切分邏輯也有差異。而使用 Spark 這種大數據框架來并行處理過重,并不合適。使用多核實例進行多進程并發處理則過于原始,任務的觀測追蹤上不太方便。所以可以選用 Amazon Glue 的 Python shell 引擎進行處理。主要有如下好處:

1.方便的按照文件粒度進行并發,并發度簡單可控。具有重試、超時等機制,方便任務的追蹤和觀察,日志直接對接到 Amazon CloudWatch;

2.方便的構建運行依賴包,通過參數–additional-python-modules 指定即可,同時 Glue Python 的運行環境中已經自帶了 opensearch_py 等依賴。

可參考如下代碼:

注意:Amazon Glue 每個賬戶默認的最大并發運行的 Job 數為 200 個,如果需要更大的并發數,需要申請提高對應的 Service Quota,可以通過后臺或聯系客戶經理。

向量化推理并行

由于切分的段落和句子相對于文檔數量也膨脹了很多倍,向量數據庫模型的推理吞吐能力決定了整個流程的吞吐能力。這里采用 SageMaker Endpoint 來部署向量化模型,一般來說為了提供模型的吞吐能力,可以采用 GPU 實例推理,以及多節點 Endpoint/Endpoint 彈性伸縮能力,Server-Side/Client-Side Batch 推理能力這些都是一些有效措施。具體到離線向量知識庫構建這個場景,可以采用如下幾種策略:

GPU 實例部署

向量化模型 CPU 實例是可以推理的。但離線場景下,推理并發度高,GPU 相對于 CPU 可以達到 20 倍左右的吞吐量提升。所以離線場景可以采用 GPU 推理,在線場景 CPU 推理的策略。

多節點 Endpoint

對于臨時的大并發向量生成,通過部署多節點 Endpoint 進行處理,處理完畢后可以關閉*(注意:離線生成的請求量是突然增加的,Auto Scaling 冷啟動時間 5-6 分鐘,會導致前期的請求出現錯誤)*

利用 Client-Side Batch 推理

離線推理時,Client-side batch 構造十分容易。無需開啟 Server-side Batch 推理,一般來說 Sever-side batch 都會有個等待時間,如 50ms 或 100ms,對于推理延遲比較高的大語言模型比較有效,對于向量化推理則不太適用。可以參考如下代碼:

OpenSearch 批量注入

Amazon OpenSearch 的寫入操作,在實現上可以通過 bulk 批量進行,比單條寫入有很大優勢。參考如下代碼:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/166345.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/166345.shtml
英文地址,請注明出處:http://en.pswp.cn/news/166345.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

案例023:基于微信小程序的童裝商城的設計與實現

文末獲取源碼 開發語言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 數據庫&#xff1a;mysql 5.7 開發軟件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序開發軟件&#xff1a;HBuilder X 小程序…

Nginx503有哪些解決辦法

還是經常見到的服務部署問題&#xff0c;今天遇見的是503&#xff1a; 503 的可能原因 Nginx 返回 503 錯誤通常表示服務暫時不可用。一些常見的原因包括&#xff1a; 后端服務故障&#xff1a;后端服務可能由于程序錯誤、崩潰或異常情況而無法正常響應請求。這可能是由于服…

在vue或者react或angular中,模板表達式中的箭頭函數是無效的嗎?為什么無效?

出現此問題的背景&#xff1a; 我在Angular項目中對一個標簽屬性綁定了一個箭頭函數&#xff0c;編譯報錯。 在vue或者react或angular中&#xff0c;模板表達式中的箭頭函數是無效的嗎&#xff1f; 在 Vue、React 或 Angular 中&#xff0c;模板表達式中的箭頭函數是無效的。…

Java常量池理論篇:Class常量池、運行時常量池、String常量池、基本類型常量池,intern方法1.6、1.7的區別

文章目錄 Class常量池運行時常量池String常量池基本類型常量池Integer 常量池Long 常量池 加餐部分 Class常量池 每個Class字節碼文件中包含類常量池用來存放字面量以及符號引用等信息。 運行時常量池 java文件被編譯成class文件之后&#xff0c;也就是會生成我上面所說的 …

webshell之基于框架免殺

thinkphp array_map_recursive函數 array_map_recursive函數分析 這里存在一個call_user_func命令執行函數 免殺效果 B函數 免殺效果 B函數分析 exec函數分析 在exec函數用存在有個類調用&#xff0c;且所有的參數都可控 smarty_php_tag函數 免殺效果 smarty_php_tag函數分析…

【開源】基于Vue.js的數據可視化的智慧河南大屏

項目編號&#xff1a; S 059 &#xff0c;文末獲取源碼。 \color{red}{項目編號&#xff1a;S059&#xff0c;文末獲取源碼。} 項目編號&#xff1a;S059&#xff0c;文末獲取源碼。 目錄 一、摘要1.1 項目介紹1.2 項目錄屏 二、功能模塊三、系統展示四、核心代碼4.1 數據模塊 …

HTML新手入門筆記整理:塊元素和行內元素

塊元素 在HTML中&#xff0c;塊元素在瀏覽器顯示狀態下獨占一行&#xff0c;并且排斥其他元素與其位于一行。一般情況下&#xff0c;塊元素內部可以容納其他塊元素和行內元素。 常見塊元素 塊元素 說明 h1~h6 標題元素 p 段落元素 div div元素 hr 水平線 ol 有序列…

打印菱形-第11屆藍橋杯選拔賽Python真題精選

[導讀]&#xff1a;超平老師的Scratch藍橋杯真題解讀系列在推出之后&#xff0c;受到了廣大老師和家長的好評&#xff0c;非常感謝各位的認可和厚愛。作為回饋&#xff0c;超平老師計劃推出《Python藍橋杯真題解析100講》&#xff0c;這是解讀系列的第9講。 打印菱形&#xff…

周轉箱與工具柜的智能化應用

在當今制造業激烈競爭的市場中&#xff0c;6S管理方法作為提高企業競爭力的有力工具&#xff0c;與精益生產中的周轉箱和工具柜相結合&#xff0c;將為企業帶來更大的優勢。通過實施6S管理方法&#xff0c;企業不僅能夠提高生產效率、降低成本&#xff0c;還能夠改善產品質量、…

GDPU 數據結構 天碼行空11

文章目錄 數據結構實驗十一 圖的創建與存儲一、實驗目的二、實驗內容三、【實驗源代碼】&#x1f37b; CPP版&#x1f37b; c 語言版&#x1f37b; java版 四、【實驗結果】五、【實驗總結】 數據結構實驗十一 圖的創建與存儲 一、實驗目的 1、 理解圖的存儲結構與基本操作&a…

nf_conntrack內核模塊常見問題

nf_conntrack內核模塊常見問題 問題描述排查步驟前置條件&#xff1a;啟用nf_conntrack內核模塊檢查nf_conntrack配置 解決辦法1:半數減少nf_conntrack buckets的值解決辦法2:加倍調大m.min_free_kbytes值解決辦法3:Linux社區權威答復-忽略告警 問題描述 內核報錯 falling bac…

什么是 npm —— 寫給初學者的編程教程

原文鏈接&#xff1a; 什么是 npm —— 寫給初學者的編程教程 自 2009 年以來&#xff0c;Node.js 一直席卷全球。成千上萬個系統基于 Node.js 構建&#xff0c;促使開發者在社區宣稱“JavaScript 正在吞噬軟件”。 Node 成功的主要因素之一是它廣受歡迎的軟件包管理器——np…

前k個高頻單詞(C++實現)

前k個高頻單詞 題目思路代碼代碼講解 題目 思路 通過統計字符串的出現次數&#xff0c;并根據出現次數和字典序對字符串進行排序&#xff0c;找出出現頻率最高的前k個字符串。使用一個自定義的仿函數作為排序的比較函數&#xff0c;通過map容器進行統計&#xff0c;然后將結果…

Linux:strace 簡介

文章目錄 1. 前言2. 什么是 strace ?3. 使用 strace3.1 追蹤指定進程3.1.1 通過程序名追蹤進程3.1.2 通過 進程 ID (PID) 追蹤程序3.1.3 追蹤 子進程 或 線程 3.2 系統調用情況統計3.3 追蹤過濾3.3.1 追蹤指定的系統調用集合3.3.2 追蹤對指定文件句柄集合操作的系統調用3.3.3 …

前端已死?看看我的秋招上岸歷程

背景 求職方向&#xff1a;web前端 技術棧&#xff1a;vue2、springboot&#xff08;學校開過課&#xff0c;簡單的學習過&#xff09; 實習經歷&#xff1a;兩段&#xff0c;但都是實訓類的&#xff0c;說白了就是類似培訓&#xff0c;每次面試官問起時我也會坦誠交代&…

關于鴻蒙網絡請求的問題

https://developer.huawei.com/consumer/cn/forum/topic/0204136145853212268?fid0102683795438680754 鴻蒙OS 代碼 import http from ohos.net.http;export const httpUtils (url: string, data: any) > {return new Promise((resolve, reject) > {let httpRequest …

創意設計與個性化定制:酒精壁爐的獨特之處

在當今家居裝飾的潮流中&#xff0c;人們越來越注重個性化和創意&#xff0c;而酒精壁爐正是在這一趨勢中嶄露頭角。它不僅成為家居的溫馨之選&#xff0c;更因其設計的靈活性而成為創意焦點&#xff0c;吸引了越來越多注重家居設計的人群。 酒精壁爐的設計靈活性為家居注入了新…

vue的package.json詳細說明

前言 package.json 文件是一個非常重要的文件,它用于存儲關于項目的元信息以及依賴項。在 Vue.js 項目中,package.json 文件描述了項目的名稱、版本、描述、作者、依賴項、腳本命令等信息。 說明 package.json 文件常見的 詳細說明: 1.名稱 (name): 項目的名稱。遵循反向…

工作流引擎架構設計

一個應用MIS的系統的架構離不開工作流引擎&#xff0c;具有流程引擎思維的架構人員設計系統的時候就有流程的思維&#xff0c;他區別于過程思維&#xff0c;過程思維開發出來的系統&#xff0c;用戶面對的是菜單、模塊。而流程思維設計出來的系統就是發起、待辦、在途、查詢、近…

SELinux refpolicy詳解(2)

接前一篇文章:SELinux refpolicy詳解(1) 本文內容引自: Documentation SELinuxProject/refpolicy Wiki GitHub 4. 入門指南 文檔是參考策略的主要目標之一。入門指南(https://github.com/SELinuxProject/refpolicy/wiki/GettingStarted)提供了有關編寫參考策略模塊的…