將RAG與Semantic Search融入LLM:提升準確性與效率

更新於 2024/12/17閱讀時間約 24 分鐘

前言

前幾篇分享了 IBM Watsonx.ai 平台,以及在平台上使用 LLM 完成客戶體驗分析、與LLM串連處理較複雜的問題。在這一篇中,我們想來嘗試使用檢索增強生成(RAG)的技術,RAG 通過整合外部數據來增強基礎模型的回答能力,這不僅能解決模型訓練數據的局限性問題,還可以提供更精準和相關的信息,甚至是回答專業領域問題,以及處理大型文檔任務時,能夠更精準,且不容易發生憑空想像的問題。

raw-image


RAG基本介紹

RAG 技術是一種結合了搜尋檢索和生成能力的自然語言處理架構,它可以從外部知識庫搜尋相關信息,然後使用這些信息來生成回應或完成特定的 NLP 任務。

RAG 模型主要由兩個部分構成:檢索器和生成器。

  1. 檢索器負責從外部知識庫(例如,文本數據庫或預先訓練的知識嵌入)中檢索相關的知識訊息
  2. 生成器會利用檢索到的知識來生成回應。

透過這個架構,模型可以從大量的文本數據中找到與問題相關的答案,並生成結構化的回應。RAG 技術的優點是利用大量的真實數據,得出更準確及更具有語境的回答。

為什麼需要 RAG

它主要解決大型語言模型處理即時訊息,以及更新資訊的限制:

  1. 處理即時或最新信息: 傳統的大型語言模型在特定時間點的數據快照上進行訓練,因此它們僅能回答訓練數據中包含的信息。例如,問一個 LLM 今天的天氣如何,它可能無法回答,因為今天的天氣信息不包含在它的訓練數據中。RAG 透過探索即時天氣的 API 或相關信息來獲得資訊,並在閱讀這些 API 的結果後,生成需要的答案,以彌補處理即時問題的限制。
  2. 提供更準確和相關的回答: 通過檢索和整合與用戶查詢相關的外部信息,RAG 能夠使模型提供更準確、更具相關性的答案。這對於需要專業知識或特定領域信息的查詢特別有用,這些專業知識可能來自某些長篇的文件中,那就很適合透過 RAG 去檢索與生成,且生成的內容也會根據此長文,導出精確的回答。
  3. 擴展模型的應用範圍: RAG 通過整合不同的數據源(如實時API數據、專業文件等),使模型能夠解答原本超出其訓練範圍的問題,從而擴展了模型的應用範圍。
  4. 優化成本和效率: 對於需要處理大量文檔或數據的場景,RAG 可以通過只檢索和處理與特定查詢最相關的信息,來提高處理效率和降低運算成本。

語義檢索(Semantic Search)基本介紹

與RAG緊密相連的另一項關鍵技術是語義檢索。語義檢索技術主要用於從大規模數據集中快速識別出與特定查詢語義上最相關的信息片段。這種技術通過將文本轉換為數值向量(嵌入),並計算這些向量之間的相似度,來確定哪些文本片段與用戶的查詢最為匹配。

如果想讓模型回答關於一本潛水艇手冊(長達492頁)的問題,直接將整本手冊作為上下文提供給模型是不切實際的。這是因為這樣的大量文本會超過模型的處理能力和最大標記限制。此外,由於基於使用的 token 數計費,過長的提示會導致成本增加。

這種情況下,語義檢索(Semantic Search)技術就顯得非常重要。其核心思想是將大型文檔分解成較小的文本片段。這樣不僅使得文本處理和檢索變得更高效,也使整個過程更經濟實用。

具體來說,我們將文本片段轉換成 vector,然後測量這些向量之間的距離,從而識別出與用戶提問在語義上最接近的文本片段。這樣,我們就只需將最相關的文本部分作為上下文提供給模型,而不是整個大型文檔。總而言之,透過將大型文檔分解並使用語義檢索技術,我們可以更高效地利用語言模型來回答複雜和專業的問題,同時控制成本和提升回答的準確性。

實作

RAG 回答 PDF 問題

導入 pdf 文件

def pdf_to_text(path: str,
start_page: int = 1,
end_page: Optional[int or None] = None) -> list[str]:
"""
Converts PDF to plain text.

Params:
path (str): Path to the PDF file.
start_page (int): Page to start getting text from.
end_page (int): Last page to get text from.
"""
loader = PyPDFLoader(path)
pages = loader.load()
total_pages = len(pages)

if end_page is None:
end_page = len(pages)

text_list = []
for i in range(start_page-1, end_page):
text = pages[i].page_content
text = text.replace('\n', ' ')
text = re.sub(r'\s+', ' ', text)
text_list.append(text)

return text_list

text_list = pdf_to_text("pdfs/DQ2.pdf")
print(text_list[:2])
raw-image

文字預處理

以頁為單位分割,並記錄每個片段的頁碼。

def text_to_chunks(texts: list[str],
start_page: int = 1) -> list[list[str]]:
"""
Splits the text into equally distributed chunks.

Args:
texts (str): List of texts to be converted into chunks.
word_length (int): Maximum number of words in each chunk.
start_page (int): Starting page number for the chunks.
"""
text_toks = [t.split(' ') for t in texts]
chunks = []

for idx, words in enumerate(text_toks):

chunk = ' '.join(words).strip()
chunk = f'[Page no. {idx+start_page}]' + ' ' + '"' + chunk + '"'
chunks.append(chunk)

return chunks

chunks = text_to_chunks(text_list)

轉換成 vector 使用 text embeddings

應用 hugging dace 的 universal-sentence-encoder_4 模型將文字轉換成 vector

def get_text_embedding(texts: list[list[str]],
batch: int = 1000) -> list[Any]:
"""
Get the embeddings from the text.

Args:
texts (list(str)): List of chucks of text.
batch (int): Batch size.
"""
embeddings = []
for i in range(0, len(texts), batch):
text_batch = texts[i:(i+batch)]
# Embeddings model
emb_batch = emb_function(text_batch)
embeddings.append(emb_batch)
embeddings = np.vstack(embeddings)
return embeddings

embeddings = get_text_embedding(chunks)

print(embeddings.shape)
print(f"Our text was embedded into {embeddings.shape[1]} dimensions")

可視化 Semantic Search

剛剛轉換成 384 維度的向量,我們使用 t-SNE 算法,降到二維,讓我們可以就圖形做觀察

# Create a t-SNE model
tsne = TSNE(n_components=2, random_state=42)
embeddings_with_question = np.vstack([embeddings, emb_question])
embeddings_2d = tsne.fit_transform(embeddings_with_question)
def visualize_embeddings(embeddings_2d: np.ndarray,
question: Optional[bool] = False,
neighbors: Optional[np.ndarray] = None) -> None:
"""
Visualize 384-dimensional embeddings in 2D using t-SNE, label each data point with its index,
and optionally plot a question data point as a red dot with the label 'q'.

Args:
embeddings (numpy.array): An array of shape (num_samples, 384) containing the embeddings.
question (numpy.array, optional): An additional 384-dimensional embedding for the question.
Default is None.
"""

# Scatter plot the 2D embeddings and label each data point with its index
plt.figure(figsize=(10, 8))
num_samples = embeddings.shape[0]
if neighbors is not None:
for i, (x, y) in enumerate(embeddings_2d[:num_samples]):
if i in neighbors:
plt.scatter(x, y, color='purple', alpha=0.7)
plt.annotate(str(i), xy=(x, y), xytext=(5, 2), textcoords='offset points', color='black')
else:
plt.scatter(x, y, color='blue', alpha=0.7)
plt.annotate(str(i), xy=(x, y), xytext=(5, 2), textcoords='offset points', color='black')
else:
for i, (x, y) in enumerate(embeddings_2d[:num_samples]):
plt.scatter(x, y, color='blue', alpha=0.7)
plt.annotate(str(i), xy=(x, y), xytext=(5, 2), textcoords='offset points', color='black')

# Plot the question data point if provided
if question:
x, y = embeddings_2d[-1] # Last point corresponds to the question
plt.scatter(x, y, color='red', label='q')
plt.annotate('q', xy=(x, y), xytext=(5, 2), textcoords='offset points', color='black')

plt.title('t-SNE Visualization of 384-dimensional Embeddings')
plt.xlabel('Dimension 1')
plt.ylabel('Dimension 2')
plt.show()
visualize_embeddings(embeddings_2d[:-1])
raw-image


我們要透過文字片段的距離,來找到可能包含問題答案的片段,這裡的距離選用歐幾里德距離計算相似度與接近性,採用最近鄰居(NearestNeighbors)算法,選擇最接近的 k 個數據,k 定為 5。

nn_2d = NearestNeighbors(n_neighbors=5, metric='cosine')
nn_2d.fit(embeddings_2d[:-1])
neighbors = nn_2d.kneighbors(embeddings_2d[-1].reshape(1, -1), return_distance=False)
neighbors

再將它可視化

visualize_embeddings(embeddings_2d, True, neighbors)
raw-image

紫色的點是比較靠近的。

使用 Semantic Search找最近的片段

question = '如何查詢成交明細?'
emb_question = emb_function([question])
neighbors = nn.kneighbors(emb_question, return_distance=False)
neighbors

準備 prompt

def build_prompt(question):
prompt = ""


prompt += "[INST] <<SYS>>You are an AI assistant tasked with providing answers by summarizing related documents. You should follow these rules:\n"\
"1. Summarize the content from the provided documents, using the following format:\n"\
"Topic of the Document: Describe the topic of the document.\n"\
"Step by Step Instruction: Provide user question-specific instructions or information from the document.\n"\
"2. If no relevant information is found in the chat history, respond with \"I can't answer the question\".\n"\
"By adhering to these rules, you will help users find accurate and valuable information.\n"\
"<</SYS>>\n"

prompt += 'Search results:\n'

for c in topn_chunks:
prompt += c + '\n\n'
prompt += f"\n\n\nQuery: {question}\n\nAnswer: [/INST]"

return prompt
prompt = build_prompt(question)
print(prompt)
raw-image

最後了! inference

def send_to_watsonxai(prompts,
model_name="meta-llama/llama-2-70b-chat",
decoding_method="greedy",
max_new_tokens=512,
min_new_tokens=0,
repetition_penalty=1.0
):
'''
helper function for sending prompts and params to Watsonx.ai

Args:
prompts:list list of text prompts
decoding:str Watsonx.ai parameter "sample" or "greedy"
max_new_tok:int Watsonx.ai parameter for max new tokens/response returned
temperature:float Watsonx.ai parameter for temperature (range 0>2)
repetition_penalty:float Watsonx.ai parameter for repetition penalty (range 1.0 to 2.0)

Returns: None
prints response
'''


# Instantiate parameters for text generation
model_params = {
GenParams.DECODING_METHOD: decoding_method,
GenParams.MIN_NEW_TOKENS: min_new_tokens,
GenParams.MAX_NEW_TOKENS: max_new_tokens,
GenParams.RANDOM_SEED: 42,
GenParams.TEMPERATURE: 0,
GenParams.REPETITION_PENALTY: repetition_penalty,
}


# Instantiate a model proxy object to send your requests
model = Model(
model_id=model_name,
params=model_params,
credentials=creds,
project_id=project_id)


for prompt in prompts:
print(model.generate_text(prompt))
# Example questions for the DQ2:
# 可以怎麼查詢成交狀況?
# 有辦法查詢原物料行情嗎?
# 我想查詢指數的委買跟委賣分析
# DQ2 可以做到什麼功能?


question = "有辦法查詢原物料行情嗎?"
prompt = build_prompt(question)

send_to_watsonxai(prompts=[prompt], min_new_tokens=1)
raw-image

小心得

在了解 RAG(檢索增強生成)與語義檢索(Semantic Search)技術後,我發現雖然它們在技術層面上比之前我分享的內容來得複雜,但實際上其核心概念非常明確且直觀。這些技術的出現,主要是為了解決當前大型語言模型(LLM)在處理即時更新資訊或特定領域深度知識方面的局限性。RAG 和語義檢索這些“巧妙的方法”實際上代表了在現有技術條件下的創新與突破。我認為,隨著技術的不斷發展,這些限制很可能會很快被克服。與此同時,這些方法在節約計算資源和提高回答精確度方面的潛力也令我覺得它們非常值得嘗試和深入探究,RAG 和語義檢索不僅是當前問題的有效解決方案,也可能為未來語言模型的發展提供新的思路和靈感,感謝看到這裡的你,我們下次見!

參考


avatar-img
33會員
43內容數
歡迎來到《桃花源記》專欄。這裡不僅是一個文字的集合,更是一個探索、夢想和自我發現的空間。在這個專欄中,我們將一同走進那些隱藏在日常生活中的"桃花源"——那些讓我們心動、讓我們反思、讓我們找到內心平靜的時刻和地方
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Karen的沙龍 的其他內容
前言 在先前的文章中,我們探討了 IBM Watsonx 在客戶滿意度分析中的應用。今天,我們將利用 Google 的兩款大型語言模型(LLM)— flan-ul2 和 flan-t5-xxl,展示它們如何串聯起來生成關於特定主題的隨機問題和回答。 在這篇文章中,將使用 SimpleSequen
前言 在上一篇文章中,分享了第一次使用 IBM Watsonx 的經歷,以及我對 Prompt lab 功能的初步探索。繼續這個話題,本文將探討 Watsonx 平台對 Python SDK 的支持,以及實作幾個 LLM 的應用,這一特性為開發者提供了極大的便利,使得在此平台上進行開發和應用大型語
前言 在這個迅速變化的技術世界裡,AI 已成為推動創新和效率的主要動力之一,最近很幸運得參加了IBM Watsonx 的 workshop,對我來說是一個很好的機會認識企業對於快速導入AI和整合AI應用的平台。IBM Watson 作為AI領域的先驅之一,長久以來一直在智慧型系統和認知計算方面處於
在數據科學和機器學習中,特徵工程是提高模型性能的關鍵步驟之一,通過創建新特徵或轉換現有特徵,我們可以更好地捕捉數據中的信息,提高模型的預測能力。然而,當處理大數據集時,特徵工程可能變得耗時,而且若是在研發階段,特徵其實是需要快速迭代去產生並且做後續的實驗,這也是近期遇到的問題,因此想在這篇文章實作多
1. 問題定義 每一個成功的模型都始於明確的問題定義! 核心思考:你的模型想要達到什麼目的? 例如:是要偵測每一筆交易是否涉及洗錢,還是要從大量資料中找出可能的洗錢關聯戶? 2. 數據檢查 數據是模型的基石,但不是所有數據都是有用的! 核心思考:你的數據夠嗎?時間分佈如何?正負樣本
今年的國泰金控技術年會,關於 AI 有幾個主題覺得很有趣、也受到一些啟發: 1. 可解釋 AI : AI 的可解釋性一直是一個很被關注的題目,尤其是發生在模型要準備落地應用,需要驗證黑盒子是不是依照正確的邏輯、人類的邏輯去判斷問題,我自己很喜歡這個部分,算法是用一套最基本的SHAP,SHAP基於博
前言 在先前的文章中,我們探討了 IBM Watsonx 在客戶滿意度分析中的應用。今天,我們將利用 Google 的兩款大型語言模型(LLM)— flan-ul2 和 flan-t5-xxl,展示它們如何串聯起來生成關於特定主題的隨機問題和回答。 在這篇文章中,將使用 SimpleSequen
前言 在上一篇文章中,分享了第一次使用 IBM Watsonx 的經歷,以及我對 Prompt lab 功能的初步探索。繼續這個話題,本文將探討 Watsonx 平台對 Python SDK 的支持,以及實作幾個 LLM 的應用,這一特性為開發者提供了極大的便利,使得在此平台上進行開發和應用大型語
前言 在這個迅速變化的技術世界裡,AI 已成為推動創新和效率的主要動力之一,最近很幸運得參加了IBM Watsonx 的 workshop,對我來說是一個很好的機會認識企業對於快速導入AI和整合AI應用的平台。IBM Watson 作為AI領域的先驅之一,長久以來一直在智慧型系統和認知計算方面處於
在數據科學和機器學習中,特徵工程是提高模型性能的關鍵步驟之一,通過創建新特徵或轉換現有特徵,我們可以更好地捕捉數據中的信息,提高模型的預測能力。然而,當處理大數據集時,特徵工程可能變得耗時,而且若是在研發階段,特徵其實是需要快速迭代去產生並且做後續的實驗,這也是近期遇到的問題,因此想在這篇文章實作多
1. 問題定義 每一個成功的模型都始於明確的問題定義! 核心思考:你的模型想要達到什麼目的? 例如:是要偵測每一筆交易是否涉及洗錢,還是要從大量資料中找出可能的洗錢關聯戶? 2. 數據檢查 數據是模型的基石,但不是所有數據都是有用的! 核心思考:你的數據夠嗎?時間分佈如何?正負樣本
今年的國泰金控技術年會,關於 AI 有幾個主題覺得很有趣、也受到一些啟發: 1. 可解釋 AI : AI 的可解釋性一直是一個很被關注的題目,尤其是發生在模型要準備落地應用,需要驗證黑盒子是不是依照正確的邏輯、人類的邏輯去判斷問題,我自己很喜歡這個部分,算法是用一套最基本的SHAP,SHAP基於博
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
隨著人工智慧AI晶片的興起,CoWoS(Chip-on-Wafer-on-Substrate)先進封裝技術成為了業界關注的焦點。作為金融領域的專家,江鳴業對此進行了深入的剖析,他認為,這不僅將對半導體行業帶來變革性的影響,更將在股市中掀起一股新的投資熱潮。 CoWoS先進封裝的技術優勢與市場需
Thumbnail
近日,財政部公佈的前11月稅收資料顯示,總稅收達到新臺幣3兆5713億元,同比增長8.6%,不僅創下了同期新高,還超出了全年預算目標3377億元。這一亮眼成績主要得益於所得稅、證交稅等主力稅目的強勁表現。對此,知名金融專家江鳴業認為,這一系列資料不僅反映了經濟活動的活躍程度,也為股市及金融市場的未來
Thumbnail
如果你因被背叛丟失了一座城池, 那就整頓兵馬, 繼續地攻城掠地. 有一天你所有的會比你失去的還多. 背叛者讓天來收.
Thumbnail
最近看到一間學校正在施工,挖土機開始剷除孩子本可以在上自由自在奔跑的綠意草皮,詢問之下得知該學校要重新鋪上人工草皮,主要是希望足球隊可以有更佳「專業」的場地,以及困擾於雨天積水之類的原因等等,算是學校的政績之一。 看著了無生氣地的巨型機器停駐在滿目瘡痍的侵蝕土土壤上,心中不由得一陣感嘆,為了所謂的
Thumbnail
財政部最新公佈的海關進出口貿易初步統計資料顯示,11月出口金額達到410.9億美元,年增9.7%,累計前11個月出口總額為4315億美元,年增9.9%,規模創下歷年同期次高紀錄。金融分析師江鳴業認為,這一出口表現展現了臺灣經濟的韌性,尤其是在全球經濟不確定性較高的情況下,出口資料的穩定增長為整體經濟
Thumbnail
我們一直認為只要我更努力工作,我就會更成功,而成功了,我就會快樂了。我們慣用的這個幸福公式,是成立的嗎? Good Think Inc.的執行長、美國作家尚恩˙阿喬爾Shawn Achor卻在TedTalk中給了一種新的思考方式:成功不會引領你快樂,但快樂會讓你更成功!
Thumbnail
我相信很多人從小的夢想是當一位作家、或是想出書吧! 身為一個在職編輯, 就來跟大家分享出版業小知識! 首先要分享的就是書籍的出版作業! 排版、校稿、申請書號,製作一本書的步驟到底是什麼, 今天就來告訴你~
Thumbnail
我相信很多人從小的夢想是當一位作家、或是想出書吧! 身為一個在職編輯, 就來跟大家分享出版業小知識! 首先要分享的就是書籍的出版作業! 排版、校稿、申請書號,製作一本書的步驟到底是什麼, 今天就來告訴你~ 首先,書籍分為兩種, 一種是外文書,也就是翻譯書。國內目前成書大部分都以翻譯書為主
Thumbnail
瑜珈的課程與空間,讓人們都可以暫時卸下職業與社會賦予的身份,好好照顧自己的身心。例如已婚的年輕媽媽,她們可以暫時脫下母親的角色,回過頭來照顧自己。偶爾會有幾位男性報名上課,他們也可以在練習中釋放壓力、卸下種種角色於責任,好好看顧自己的心。
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
隨著人工智慧AI晶片的興起,CoWoS(Chip-on-Wafer-on-Substrate)先進封裝技術成為了業界關注的焦點。作為金融領域的專家,江鳴業對此進行了深入的剖析,他認為,這不僅將對半導體行業帶來變革性的影響,更將在股市中掀起一股新的投資熱潮。 CoWoS先進封裝的技術優勢與市場需
Thumbnail
近日,財政部公佈的前11月稅收資料顯示,總稅收達到新臺幣3兆5713億元,同比增長8.6%,不僅創下了同期新高,還超出了全年預算目標3377億元。這一亮眼成績主要得益於所得稅、證交稅等主力稅目的強勁表現。對此,知名金融專家江鳴業認為,這一系列資料不僅反映了經濟活動的活躍程度,也為股市及金融市場的未來
Thumbnail
如果你因被背叛丟失了一座城池, 那就整頓兵馬, 繼續地攻城掠地. 有一天你所有的會比你失去的還多. 背叛者讓天來收.
Thumbnail
最近看到一間學校正在施工,挖土機開始剷除孩子本可以在上自由自在奔跑的綠意草皮,詢問之下得知該學校要重新鋪上人工草皮,主要是希望足球隊可以有更佳「專業」的場地,以及困擾於雨天積水之類的原因等等,算是學校的政績之一。 看著了無生氣地的巨型機器停駐在滿目瘡痍的侵蝕土土壤上,心中不由得一陣感嘆,為了所謂的
Thumbnail
財政部最新公佈的海關進出口貿易初步統計資料顯示,11月出口金額達到410.9億美元,年增9.7%,累計前11個月出口總額為4315億美元,年增9.9%,規模創下歷年同期次高紀錄。金融分析師江鳴業認為,這一出口表現展現了臺灣經濟的韌性,尤其是在全球經濟不確定性較高的情況下,出口資料的穩定增長為整體經濟
Thumbnail
我們一直認為只要我更努力工作,我就會更成功,而成功了,我就會快樂了。我們慣用的這個幸福公式,是成立的嗎? Good Think Inc.的執行長、美國作家尚恩˙阿喬爾Shawn Achor卻在TedTalk中給了一種新的思考方式:成功不會引領你快樂,但快樂會讓你更成功!
Thumbnail
我相信很多人從小的夢想是當一位作家、或是想出書吧! 身為一個在職編輯, 就來跟大家分享出版業小知識! 首先要分享的就是書籍的出版作業! 排版、校稿、申請書號,製作一本書的步驟到底是什麼, 今天就來告訴你~
Thumbnail
我相信很多人從小的夢想是當一位作家、或是想出書吧! 身為一個在職編輯, 就來跟大家分享出版業小知識! 首先要分享的就是書籍的出版作業! 排版、校稿、申請書號,製作一本書的步驟到底是什麼, 今天就來告訴你~ 首先,書籍分為兩種, 一種是外文書,也就是翻譯書。國內目前成書大部分都以翻譯書為主
Thumbnail
瑜珈的課程與空間,讓人們都可以暫時卸下職業與社會賦予的身份,好好照顧自己的身心。例如已婚的年輕媽媽,她們可以暫時脫下母親的角色,回過頭來照顧自己。偶爾會有幾位男性報名上課,他們也可以在練習中釋放壓力、卸下種種角色於責任,好好看顧自己的心。