2024-08-22 | Superteams
介紹
Gemma 是 Google 在人工智慧領域最新推出的 LLM 系列,它不僅僅是另一個大型語言模型。這是一個「開放模型」系列,意味著它們的核心功能可以免費存取。值得注意的是,Google 在最近的 Gemini 升級後,立即發布了 Gemma 作為開放模型。
Gemma 有兩種大小 – 20 億和 70 億參數 – 分別稱為 Gemma 2b 和 Gemma 7b。Gemma 功能強大,與 Llama2 等其他開源模型相比,它在相對較小的模型大小下實現了最先進的效能。這些較小的模型甚至適合作為筆記型電腦或桌上型電腦上的 LLM,使它們成為開發者進行實驗的理想選擇。
Google 在 Gemma 上做了一件重要的事情是,它實施了嚴格的標準,以確保安全和公正的輸出,解決了對大型語言模型可能被濫用的擔憂。此外,他們還為 Kaggle 和 Google Cloud 等平台上的研究和開發提供免費配額。
在本文中,我們將探索 Gemma 2b,並使用 LangChain 和我們非常喜愛的向量資料庫 Qdrant 建立 RAG 應用程式。
但在此之前,我們為什麼需要 RAG 管道?另外,還有關於 Gemma 模型的技術簡介。
Gemma 模型技術簡介
Google已經採取了一些措施來簡化開發人員的採用,以便開發人員可以嘗試。
架構和框架支持
- 多框架工具:Gemma 提供跨各種框架的推理和微調的參考實現,包括 Keras 3.0、PyTorch、JAX 和 Hugging Face Transformers。
- 跨裝置相容性:Gemma 可跨不同裝置運行,例如筆記型電腦、桌上型電腦、物聯網 (IoT) 裝置、手機和雲端環境。
- 硬體整合:Gemma 利用尖端硬體平台,特別是 NVIDIA GPU,確保最佳效能並與先進技術整合。
性能和安全特性
- 模型變體:Gemma 提供兩種尺寸 — Gemma 2B 和 Gemma 7B,每種尺寸都有經過預先訓練和指令調整的變體。
- 安全和負責任的生成:Gemma 經過預先訓練,可以過濾敏感或個人訊息,並使用人類回饋的強化學習 (RLHF) 來最大程度地減少產生有害內容的可能性。
- 手動測試:進行手動紅隊和對抗性測試來識別與 Gemma 相關的潛在風險。
可訪問性和協作
- 開源:Gemma 免費提供給全球開發人員和研究人員社群。
- 工具鏈支援:Gemma 提供跨所有主要框架的推理和監督微調 (SFT) 工具鏈。
- 即用型資源:Gemma 隨附即用型 Colab 和 Kaggle 筆記本,並與 Hugging Face、MaxText、NVIDIA NeMo 和 TensorRT-LLM 等熱門工具整合。
- 免費積分:首次使用 Google Cloud 的用戶可以獲得 300 美元的積分,研究人員可以申請額外的 Google Cloud 積分,最高可達 50 萬美元。
截至目前,Gemma 僅專注於文本到文本的任務,與其前身 Gemini 不同,Gemini 是多模式的。
儘管如此,Gemma 似乎表現出了與其尺寸相關的出色性能,在關鍵基準上超越了更大的型號,同時保持了嚴格的安全和責任標準
了解 RAG 管道
(如果您已經熟悉 RAG 及其重要性,則可以跳過本節。)
雖然LLM擅長處理語言和生成創意文本,但他們在將自己的回答立足於現實世界的事實和知識方面存在局限性。
這就是 RAG 管道的用武之地,它透過解決這些限制,在 LLM 的「基礎」方面發揮著至關重要的作用。它們結合了兩個強大的 AI 組件的優勢:大型語言模型 (LLM) 和向量資料庫。以下是它們的工作原理的詳細說明:
第 1 步 – 知識準備
文件收集:相關文件(例如文章、報告或程式碼)被收集並儲存在資料庫中。
向量化:使用嵌入模型將每個文件轉換為稱為「向量」的數字表示。將其想像為在多維空間中捕獲文件的本質。
向量資料庫:所有文件向量都有效地儲存在專為快速相似性搜尋而設計的專用資料庫中。
步驟 2. 使用者交互
使用者查詢:您向LLM提出問題或提供說明。
查詢向量化:您的查詢也會使用相同的嵌入模型轉換為向量。
步驟3.資訊檢索
相似性搜尋:LLM 的查詢向量與資料庫中的所有文件向量進行比較。檢索具有最接近向量表示的文檔,表示它們包含相關資訊。
過濾和重新排名(可選):其他模型可以根據相關性、上下文或其他標準細化檢索到的文件。
步驟 4. 知識整合
上下文豐富:檢索到的文件將作為附加資訊提供給LLM。這有助於LLM了解您查詢的上下文並從相關來源存取特定詳細資訊。
步驟 5. 響應生成
工作中的LLM:透過豐富的上下文,LLM可以產生回應。這可以是您問題的答案、根據您的指示撰寫的創意文本,或是LLM接受培訓的任何其他輸出。
問題陳述:建立 RAG 管道來查詢履歷
在接下來的步驟中,我們將使用大量候選人的履歷作為我們的資料集。這是一個很好的應用場景,因為人力資源主管經常需要瀏覽數千份候選人的履歷,才能找到適合某個職位的應徵者。
借助 LLM 和 RAG 應用程式,可以顯著提升人力資源主管的工作效率,並為他們提供一個簡單的履歷查詢工具。實際上,我們之前已經透過 Mistral 7b LLM 部署了這樣的解決方案。
在本文中,我們將嘗試對 Gemma 2b 進行相同的操作。相較之下,這個 LLM 的規模較小,但希望結果同樣出色。
第1步:安裝
讓我們使用您喜歡的任何筆記型電腦環境。就我們而言,我們傾向於在 Google Cloud 上啟動一個節點,Google Cloud 慷慨地為我們提供了免費的啟動配額。在本例中,我們將使用已經運行的 4xT4 節點。為了連接到遠端節點,我們將使用 VS Code Remote Explorer 擴充功能,並建立 SSH 連線。
儘管這個模型有可能在我的筆記型電腦上運行,但我想展示的是在具有大量記憶體和大型資料集的 GPU 上建立的實際用例。

安裝擴充後,建立一個新的 ssh 連線。步驟很明顯,它會讓你進入機器。然後,我喜歡總是創建一個名為“workspace”的資料夾,然後創建一個類似“gemma_rag”的資料夾。
mkdir -p ~/workspace/gemma_rag
在該資料夾中建立一個筆記本,例如「gemma_test.ipynb」。這將為您提供強大的 GPU 支援的筆記型電腦環境。接下來,選擇一個核心。當您選擇右側的核心時,VS Code 將允許您遠端建立虛擬環境。這將在同一目錄中建立一個 .venv 資料夾。
現在讓我們安裝一些函式庫:
!pip install tiktoken
!pip install qdrant-client langchain pypdf
接下來是 import 語句。
import os
import getpass
from operator import itemgetter
from langchain_community.document_loaders import PyPDFDirectoryLoader
from langchain.vectorstores import Qdrant
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough, RunnableParallel
from langchain.schema import format_document
from langchain.llms import HuggingFacePipeline
from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.chains import RetrievalQA
我使用 VS Code 本身建立了一個名為「data」的資料夾。之後,我只是將大約一千份履歷拖到該資料夾中。足夠適合測試了。
現在,讓我們加載這些:
loader = PyPDFDirectoryLoader("./data")
docs = loader.load()
print(len(docs))
這應該會列印已從目錄載入的文件總數。接下來,我們將使用 HuggingFaceEmbeddings() 函數將這些文件轉換為向量嵌入。我們將把它保存到一個名為「履歷」的集合中。在這裡,我們只是在“內存”模式下使用 Qdrant。理想情況下,您應該透過 docker 啟動 Qdrant,或使用他們的雲端。
首先確保您安裝了句子轉換器。
!pip install sentence-transformers
現在繼續進行向量嵌入轉換。
from langchain.text_splitter import RecursiveCharacterTextSplitter
# initialise embeddings used to convert text to vectors
model_name = "sentence-transformers/all-mpnet-base-v2"
model_kwargs = {"device": "cuda"}
embeddings = HuggingFaceEmbeddings(model_name=model_name, model_kwargs=model_kwargs)
# Split documents into chunks so it fits in context
text_splitter = RecursiveCharacterTextSplitter(chunk_size = 500, chunk_overlap = 0)
all_splits = text_splitter.split_documents(docs)
# create a qdrant collection - a vector based index of all resumes
qdrant_collection = Qdrant.from_documents(
all_splits,
embeddings,
location=":memory:", # Local mode with in-memory storage only
collection_name="resumes",
)
# construct a retriever on top of the vector store
qdrant_retriever = qdrant_collection.as_retriever()
接下來,在將 RAG 管道整合在一起之前,我們將嘗試 Gemma 2b 模型。為此,我們必須先確保使用升級後的變壓器庫。
!pip install -U "transformers==4.38.0" --upgrade
接下來,我們將測試 Gemma-2b。在繼續執行下一組程式碼之前,您需要接受許可證並有權存取該模型。為此,您應該訪問以下 URL。
https://huggingface.co/google/gemma-2b-it
獲得存取權限後,您可以使用 HuggingFace 令牌,也可以在本機下載模型。我們要做前者。
from transformers import AutoTokenizer, pipeline
import torch
hf_access_token = 'hf......'
model = "google/gemma-2b-it"
# Code below is to first test out the model
tokenizer = AutoTokenizer.from_pretrained(model, token=hf_access_token)
pipeline = pipeline(
"text-generation",
model=model,
model_kwargs={"torch_dtype": torch.bfloat16},
device="cuda",
max_new_tokens=512
)
messages = [
{"role": "user", "content": "Where is Milan?"},
]
prompt = pipeline.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
outputs = pipeline(
prompt,
max_new_tokens=256,
add_special_tokens=True,
do_sample=True,
temperature=0.7,
top_k=50,
top_p=0.95
)
print(outputs[0]["generated_text"][len(prompt):])
如果到目前為止您已經完成了所有操作,您將看到以下輸出。
Milan is located in the Lombardy region of Italy. It is the largest city in the region and the second-largest city in Italy after Rome.
接下來,讓我們使用 Qdrant 和我們的履歷資料集將 RAG 管道接在一起。
gemma_llm = HuggingFacePipeline(
pipeline=pipeline,
model_kwargs={"temperature": 0.7},
)
qa = RetrievalQA.from_chain_type(
llm=gemma_llm,
chain_type="stuff",
retriever=qdrant_retriever
)
query = "Which resumes have Python experience?"
qa.invoke(query)
這應該已經為你帶來了很好的結果,你的LLM以數據為基礎。
現在讓我們在頂部放置一個 Gradio UI。
!pip install --upgrade gradio
我們現在將把它們放在一起,用履歷資料集建立我們的 RAG 管道。
import gradio as gr
import os
from shutil import copyfile
with gr.Blocks() as demo:
chatbot = gr.Chatbot()
msg = gr.Textbox()
clear = gr.ClearButton([msg, chatbot])
def respond(message, chat_history):
bot_message = qa.invoke(message)
chat_history.append((message, bot_message))
return "", chat_history
msg.submit(respond, [msg, chatbot], [msg, chatbot])
demo.launch(share=True)
結果
關於 Gemma 模型最有希望的事實之一是,儘管資源較少,但它的表現卻非常好。這很強大,因為我們將LLM視為各種場景中的自然語言引擎,從企業級聊天機器人到在手機和筆記型電腦上運行的本地LLM。前者可以幫助簡化企業工作流程,而後者將為您的日常生活提供幫助。
谷歌透過Gemma展示了在較小的模型規模下實現超越基準測試的品質是可能的,我們預計它將取代我們最喜愛的另外兩個模型——Mistral 7B 和 Llama2 7B,成為新的佼佼者
資料來源: https://www.superteams.ai/blog/steps-to-build-a-rag-pipeline-using-gemma-2b-llm