Hướng dẫn Xây dựng Chatbot AI với LLma 2 và OpenAI
11 Jan, 2025
Hướng nội
AuthorBài viết này sẽ hướng dẫn bạn cách tạo một ứng dụng hỏi-đáp từ đơn giản đến phức tạp sử dụng LLM của Meta/ OpenAI kết hợp với tài liệu nội bộ
Mục Lục
Bài viết này sẽ hướng dẫn bạn cách tạo một ứng dụng hỏi-đáp từ đơn giản đến phức tạp. Chúng ta sẽ sử dụng Langchain, một thư viện Python hỗ trợ xây dựng pipeline xử lý dữ liệu cho các ứng dụng AI, cùng với các mô hình LLM từ Meta và OpenAI. Ngoài ra, bài viết cũng giới thiệu ChromaDB, công cụ giúp tìm kiếm tài liệu dựa trên nội dung một cách nhanh chóng, cụ thể là các tài liệu liên quan đến danh sách sản phẩm và giá cả của công ty mình.
Lưu ý: Nếu các bạn chọn chạy Llama 2 thì nên dùng máy có GPU nhé vì mình đã test trên máy CPU rồi, nó không chạy nổi các bạn ạ, dù cấu hình máy mình rất mạnh nhưng có vẻ cuộc đua AI chỉ dành cho người giàu 😭. Mình thì sẽ chọn vẫn dùng máy CPU và gọi API của OpenAI thay vì phải mua máy mới chạy LLma 2.
1. Retrieval-Augmented Generation (RAG) là gì?
RAG là một phương pháp mới kết hợp giữa các hệ thống retrieval-based và generative AI. Phương pháp này cải thiện chất lượng và độ chính xác của nội dung được tạo ra bằng cách cung cấp cho Large Language Model (LLM) thông tin phù hợp từ các nguồn bên ngoài.
Hiểu đơn giản, RAG là cách kết hợp khả năng tìm kiếm thông tin của máy móc với khả năng tạo văn bản giống con người. Khi người dùng đặt câu hỏi, hệ thống sẽ tìm kiếm các tài liệu hoặc dữ liệu liên quan nhất từ bên ngoài, sau đó sử dụng LLM để tạo ra câu trả lời dựa trên cả ngữ cảnh và thông tin vừa tìm được.
Trong ví dụ này chúng ta sẽ sử dụng:
- Langchain: Là một thư viện Python giúp xây dựng các pipeline xử lý dữ liệu. Nó cho phép bạn kết nối các nguồn dữ liệu khác nhau (như tài liệu, cơ sở dữ liệu, API) và xử lý chúng một cách có tổ chức để sử dụng trong các ứng dụng AI.
- ChromaDB: Là một cơ sở dữ liệu (database) tối ưu hóa cho việc lưu trữ và tìm kiếm dữ liệu bằng cách sử dụng
vector embeddings
,vector embeddings
là cách biểu diễn thông tin (như văn bản, hình ảnh) dưới dạng các con số để máy tính có thể hiểu và so sánh. ChromaDB dùng các vector này để tìm ra những tài liệu hoặc dữ liệu có nội dung tương tự với câu hỏi hoặc yêu cầu của người dùng. - LLM Models: Mình sẽ dùng
TheBloke/Llama-2-7b-Chat-GPTQ
, dựa trên phiên bản chính thức của Facebook làLlama-2-7b-chat-hf
, được Meta tinh chỉnh (fine-tuned) trên dữ liệu hội thoại, tối ưu hóa cho nhiệm vụ chat,TheBloke/Llama-2-7b-Chat-GPTQ
là phiên bản được nén (quantized) bằng GPTQ, nhằm giảm kích thước và tăng hiệu suất trên các thiết bị như CPU và GPU có bộ nhớ thấp. Mô hình thứ 2 sẽ là GPT-4 của OpenAI.
LangChain được đặt tên để phản ánh mục tiêu chính của nó: kết hợp các mô hình ngôn ngữ lớn (LLM) với dữ liệu và logic xử lý trong một chuỗi các tác vụ liên kết với nhau. Điều này giúp xây dựng các ứng dụng NLP dễ dàng tùy chỉnh.
Ví dụ:
- Chain đơn giản: Người dùng hỏi → LLM trả lời.
- Chain phức tạp (Retrieval-Augmented Generation - RAG):
- Truy xuất thông tin từ cơ sở dữ liệu (Retrieval).
- Cung cấp ngữ cảnh này cho LLM để sinh văn bản (Generation).
2. Xây dựng ChatBot AI với LLma 2
Trong Demo mình sẽ sử dụng model Llama 2 của Facebook thay vì OpenAI vì một lý do đơn giản là nó có phí và Llama thì không. Phù hợp với các bạn nào muốn tự host một mô hình riêng cho doanh nghiệp mình và tiết kiệm chi phí (này mình không chắc nữa, chứ chi phí mua hạ tầng là mình thấy nó khủng rồi đó).
Ví dụ này có rất nhiều hạn chế và có thể không phản ánh đúng chất lượng thật sự của Llama 2, mình chưa nắm rõ cách tối ưu do thiếu tài nguyên về hạ tầng (GPU), dẫn đến không có cơ hội để làm việc nhiều với mô hình này, mong các bạn thông cảm.
2.1 Đăng kí tài khoản và tạo Token HuggingFace
- Bước 1: Các vào truy cập vào trang chủ của HuggingFace và đăng kí tài khoản bằng email của mình.
- Bước 2: Tạo Token để có thể pull sử dụng HuggingFace từ xa. Truy cập vào phần
Account
->Access Token
(Read Only), sau khi tạo xong thì bạn và lưu trữ máy nhé.
- Bước 3: Gửi yêu cầu truy xuất Model Llama cho Facebook, nếu bạn dùng model chính thức của họ. Truy cập vào đường dẫn của model Llama 2, để download được model này bằng Token của HuggingFace bạn phải gửi yêu cầu và được Meta duyệt, vị trí nằm ở ngay phần đầu tiên của repo luôn nên rất dễ thấy, thông tin trên Form khá cơ bản bao gồm: Họ, tên, email, nhu cầu sử dụng là doanh nghiệp, cá nhân. Sau khi mình yêu cầu thì tầm khoảng 1-2h sau là nhận được thông báo chấp thuận rồi.
2.2 Cài đặt các Tool liên quan đến GPU
Do máy của mình dùng card màn hình của Nvidia nên mình sẽ hướng dẫn cài các tool liên quan của Nvidia nha. Yêu cầu cho phần này là máy các bạn phải có GPU và cài sẵn Python.
- Cài CUDA Toolkit: Truy cập vào trang CUDA Toolkit, chọn hệ điều hành và download, sau khi cài đặt xong, mở termial và gõ câu lệnh
nvcc --version
như hình số 2.
- Thư viện pytorch cho GPU: Nếu các bạn chỉ dụng câu lệnh install torch thông thường thì nó sẽ không dùng GPU mà mặc định là CPU, mở terminal và chạy câu lệnh sau.
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
- Kiểm tra cài đặt pytorch: Các bạn tạo chạy các câu lệnh Python sau để kiểm tra xem đã cài đặt thành công hay chưa nhé. Nếu như màn hình hiển thị
GPU không khả dụng
thì các bước tiếp theo sẽ dùng CPU đấy nhé.
import torch
# Phiên bản PyTorch
print(f"PyTorch version: {torch.__version__}")
# Kiểm tra GPU
if torch.cuda.is_available():
print(f"GPU khả dụng: {torch.cuda.get_device_name(0)}")
print(f"CUDA version: {torch.version.cuda}")
else:
print("GPU không khả dụng.")
2.3 Xây dựng Chatbot AI hỏi đáp Đơn giản
- Bước 1: Cài đặt các thư viện cần thiết
pip install langchain openai chromadb tiktoken langchain-community transformers optimum auto-gptq
- Bước 2: Tải LLM model và xây dựng pipeline
import os
os.environ["HF_TOKEN"] = "your_token"
import torch
from langchain import HuggingFacePipeline
from transformers import AutoModelForCausalLM, AutoTokenizer, GenerationConfig, pipeline
MODEL_NAME = "TheBloke/Llama-2-7b-Chat-GPTQ"
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, use_fast=True)
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME, torch_dtype=torch.float16, trust_remote_code=True, device_map="auto"
)
generation_config = GenerationConfig.from_pretrained(MODEL_NAME)
generation_config.max_new_tokens = 1024
generation_config.temperature = 0.0001
generation_config.top_p = 0.95
generation_config.do_sample = True
generation_config.repetition_penalty = 1.15
text_pipeline = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
return_full_text=True,
generation_config=generation_config,
)
llm = HuggingFacePipeline(pipeline=text_pipeline, model_kwargs={"temperature": 0})
result = llm(
"Explain the difference between ChatGPT and open source LLMs in a couple of lines."
)
print(result)
Bạn sẽ thấy là màn hình sẽ in ra câu trả lời cho câu hỏi trên:
ChatGPT is an AI-powered chatbot developed by Meta AI that can understand and respond to user input in a conversational manner. Open source LLMs, on the other hand, are language models that are available for anyone to use, modify, and distribute under open-source licenses. These models have been trained on large datasets of text data and can be used for various natural language processing tasks such as text classification, sentiment analysis, and machine translation.
In summary, ChatGPT is a specific AI model designed for conversational dialogue, while open source LLMs are general-purpose language models that can be adapted for various NLP tasks.
3 Xây dựng Chatbot AI với OpenAI
Ví dụ này yêu cầu các bạn phải mua credit của OpenAI thì mới có thể thực hành được, về hướng dẫn mua các bạn có thể prompt trên ChatGPT. Đây cũng là phần mà mình đi khá kĩ do mình ưu tiên lựa chọn hướng tiếp cận này thay vì tự host LLM.
Trước khi bắt đầu các bạn cài thêm giúp mình một số thư viện cần thiết nữa, nếu như mình bỏ sót thư viện nào, do mình hay code Python, cài sẵn rất nhiều thư viện , thì các bạn cứ cài thêm theo như báo lỗi nhé.
pip install langchain-openai chromadb sentence-transformers google-search-results wikipedia
Nhập OpenAI key vào biến môi trường bên dưới:
import os
os.environ["OPENAI_API_KEY"] = "your_openai_key"
3.1 Chain đơn giản Hỏi & Đáp với LLM
Đây là ví dụ đơn giản nhất, các bạn hỏi và LLM trả lời.
from langchain_openai import OpenAI
client = OpenAI(max_tokens=50)
prompt = "Có bao nhiêu quốc gia ở Châu Á"
client.invoke(prompt).strip()
GPT sẽ trả ra cho chúng ta câu trả lời sau, bạn sẽ thấy câu trả lời bị mất ý, do mình giới hạn lại 50 token, demo nên tiết kiệm một tí 😝.
Châu Á là lục địa lớn nhất thế giới và có tổng cộng 48 quốc gia. Dưới đây là danh sách 48 quốc gia
3.2 Sử dụng PromptTemplate
PromptTemplate
là mẫu gợi ý được định nghĩa trước, trong đó bạn có thể thay thế các phần tử động bằng dữ liệu đầu vào.
from langchain_openai import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
client = OpenAI(max_tokens=50)
prompt = PromptTemplate.from_template("Gợi ý công ty làm {product} tốt tại Việt Nam")
chain = LLMChain(llm=client, prompt=prompt, verbose=True)
chain.invoke("nồi chiên không dầu")
Kết quả trả ra là:
{'product': 'nồi chiên không dầu',
'text': '\n\n1. Philips\n2. Midea\n3. Tefal\n4. Panasonic\n5. Electrolux\n6. KitchenAid\n7. Cuisinart\n8. Ninja\n9. Black+Decker\n'}
3.3 Kết hợp nhiều Chain lại với nhau
- SimpleSequentialChain thực hiện các chain theo thứ tự, nhưng output từ mỗi chain không được tự động gắn làm vào làm input của chain tiếp theo. Hiểu đơn giản là chúng được gắn vào cùng một flow gồm nhiều câu hỏi nối tiếp nhau (chain) nhưng đầu vào bạn phải tự kiểm soát.
from langchain.chains import SimpleSequentialChain
client = OpenAI(max_tokens=100)
# Chain 1: Tạo tên công ty
company_name_prompt = PromptTemplate.from_template("Suggest me a company name for making {product}")
company_name_chain = LLMChain(llm=client, prompt=company_name_prompt)
# Chain 2: Đề xuất chiến lược kinh doanh
company_strategies_prompt = PromptTemplate.from_template("Suggest few strategies for this company {company}")
company_strategies_chain = LLMChain(llm=client, prompt=company_strategies_prompt)
# Chuỗi thực thi đơn giản
chain = SimpleSequentialChain(chains=[company_name_chain, company_strategies_chain])
print(chain.invoke("headphones"))
- SequentialChain là phiên bản nâng cấp của SimpleSequentialChain , output của một chain sẽ tự động được chuyển làm input cho chain tiếp theo. Hiểu đơn giản nó sẽ tự động truyền từ chain 1 qua chain 2 cứ nhứ thế theo config của bạn (ghi nhớ).
from langchain.chains import SequentialChain
client = OpenAI(max_tokens=100)
# Chain 1: Tạo tên công ty
company_name_prompt = PromptTemplate.from_template("Suggest me a company name for making {product}")
company_name_chain = LLMChain(llm=client, prompt=company_name_prompt, output_key="company")
# Chain 2: Đề xuất chiến lược kinh doanh
company_strategies_prompt = PromptTemplate.from_template("Suggest few strategies for this company {company}")
company_strategies_chain = LLMChain(llm=client, prompt=company_strategies_prompt, output_key="strategies")
# Chuỗi thực thi phức tạp
chain = SequentialChain(
chains=[company_name_chain, company_strategies_chain],
input_variables=["product"],
output_variables=["company", "strategies"]
)
print(json.dumps(chain.invoke("orange juice"), indent=4))
3.3 Sử dụng Agent trong LangChain
Agent trong LangChain được thiết kế để:
- Hiểu câu hỏi của người dùng: Phân tích câu hỏi để xác định ý định của người dùng.
- Lựa chọn công cụ phù hợp: Dựa trên ngữ cảnh, Agent có thể sử dụng các công cụ (tools) như:
- Cơ sở dữ liệu vector (ChromaDB, Pinecone) để truy xuất tài liệu.
- API bên ngoài (SERP API, Wikipedia) để tìm kiếm thông tin thực tế.
- Xử lý chuỗi văn bản (string operations).
- Kết hợp thông tin: Từ các công cụ đã sử dụng để tạo ra câu trả lời phù hợp.
Bây giờ chúng ta sẽ cùng thực hiện ví dụ đơn giản dùng Agent Wikipedia nhé.
from langchain.llms import OpenAI
from langchain.agents import AgentType, load_tools, initialize_agent
client = OpenAI( max_tokens=50, temperature=0)
# Tải công cụ Wikipedia
tool = load_tools(["wikipedia"], llm=client)
# Tạo Agent với Wikipedia API
agent = initialize_agent(
tools=tool,
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
# Đặt câu hỏi
question = "Tóm tắt thông tin về Albert Einstein trong một câu."
response = agent.invoke(question)
# In kết quả
print(response)
3.3 Kết hợp LLM và Vector Database
Trong ví dụ này mình sẽ kết hợp LLM của OpenAI và tài liệu hiện có của công ty lưu trữ trong thư mục docs
, chủ yếu chứa các thông tin liên quan đến sản phẩm và giá của chúng, những tài liệu này sẽ được lưu trữ vào ChromaDB (Vector Database).
Đây là định dạng file document html của mình, các bạn nhớ lưu vào thành 1 file trong folder docs nhé.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thông tin khóa học 200Lab</title>
</head>
<body>
<p>- Hiện tại 200Lab có các khóa học sau: DevOps, Backend, Frontend với giá lần lượt là 10$, 20$, và 30$ ở hình thức học Online. Offline thì cộng thêm 10$ trên giá Online.</p>
<p>- Các hình thức thanh toán bao gồm: thẻ tín dụng, chuyển khoản và trả góp.</p>
</body>
</html>
- Bước 1: Đọc các file tài liệu định dạng html ở thư mục docs và lưu trữ vào ChromaDB.
from langchain.document_loaders import DirectoryLoader, TextLoader
loader = DirectoryLoader("docs", glob="./*.html", loader_cls=lambda path: TextLoader(path, encoding="utf-8"))
documents = loader.load()
len(documents)
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
documents = text_splitter.split_documents(documents)
len(documents)
from langchain import embeddings
from langchain_openai import OpenAIEmbeddings
db_directory = 'db'
embedding = OpenAIEmbeddings(model="text-embedding-ada-002")
from langchain.vectorstores import Chroma
vector_db = Chroma.from_documents(
documents=documents,
embedding=embedding,
persist_directory=db_directory
)
# Trả về tất cả document đã lưu
vector_db.get()
- Bước 2: Kiểm tra xem khi input 1 từ khóa thì có trả về các document liên quan không.
retriever = vector_db.as_retriever()
retriever.invoke("có những khóa học nào tại 200lab")
- Bước 3: Kết hợp với LLM của Open AI để đưa ra câu trả lời tự nhiên, mình đã cố tình không báo giá chính xác khóa học Offline để mô hình tự tính và nó đưa ra đáp án chính xác
from langchain_openai import OpenAI
from langchain.chains import RetrievalQA
chain = RetrievalQA.from_chain_type(
llm=OpenAI(),
chain_type="stuff",
retriever=retriever,
return_source_documents=False
)
chain.invoke("có những khóa học nào tại 200lab")
chain.invoke("báo giá hình thức offline cho các khóa học tại 200Lab")
Kết quả trả ra là:
{'query': 'có những khóa học nào tại 200lab',
'result': ' Hiện tại 200Lab có các khóa học sau: DevOps, Backend, Frontend với giá lần lượt là 10$, 20$, và 30$ ở hình thức học Online.'}
{'query': 'báo giá hình thức offline cho các khóa học tại 200Lab',
'result': ' Các khóa học tại 200Lab có giá lần lượt là 20$ cho khóa DevOps, 30$ cho khóa Backend, và 40$ cho khóa Frontend ở hình thức học Offline.'}
4. Kết luận
Hy vọng bài viết này của mình có thể giúp các Developer có thể "vọc" các công cụ AI, nội dung trên có thể còn rất nhiều thiếu sót do mình cũng vừa trải nghiệm vừa viết, mong nhận được những góp ý của các bạn trong tương lai.
Các bài viết liên quan: