1. Chuẩn Bị Môi Trường và Cài Đặt Phụ Thuộc
Trên nền tảng InternStudio, người dùng nên lựa chọn cấu hình GPU A100(1/4), kích hoạt terminal và bắt đầu quá trình thiết lập conda. Bước đầu tiên là sao chép bộ trọng số mô hình đã được tiền xử lý sang thư mục làm việc cá nhân:
mkdir -p /root/data/model/Shanghai_AI_Laboratory
cp -r /root/share/temp/model_repos/internlm-chat-7b /root/data/model/Shanghai_AI_Laboratory/internlm-chat-7b
Cài đặt các thư viện cốt lõi phục vụ cho framework LangChain và xử lý dữ liệu phi cấu trúc:
pip install langchain==0.0.292 gradio==4.4.0 chromadb==0.4.15 sentence-transformers==2.2.2 unstructured==0.10.30 markdown==3.3.7
Với mô hình nhúng câu (Sentence Transformer), sử dụng CLI của Hugging Face để tải xuống và lưu cục bộ. Tạo file download_hf.py trong thư mục /root/data:
import os
os.system('huggingface-cli download --resume-download sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 --local-dir /root/data/model/sentence-transformer')
Do hạn chế mạng, thư viện NLTK thường thất bại khi tải tài nguyên mặc định. Kéo về nguồn từ镜像 Gitee và giải nén thủ công:
cd /root
git clone https://gitee.com/yzy0612/nltk_data.git --branch gh-pages
cd nltk_data && mv packages/* ./
cd tokenizers && unzip punkt.zip
cd ../taggers && unzip averaged_perceptron_tagger.zip
Clone repository hướng dẫn về thư mục dữ liệu làm việc:
cd /root/data
git clone https://github.com/InternLM/tutorial
2. Xử Lý Nguồn Dữ Liệu và Mã Hóa Vectơ
Kho tri thức được xây dựng từ tài liệu Markdown và TXT của các dự án开源 thuộc Shanghai AI Laboratory như OpenCompass, LMDeploy, XTuner, XComposer, Lagent và InternLM. Module xử lý sau được tinh chỉnh để quét đệ quy, phân loại, trích xuất văn bản thuần túy, chia đoạn (chunking) và lưu trữ vào ChromaDB một cách đồng bộ:
import os
from pathlib import Path
from tqdm import tqdm
from langchain.document_loaders import UnstructuredFileLoader, UnstructuredMarkdownLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
def scan_source_directories(dir_paths):
"""Thu thập đường dẫn tuyệt đối của các tệp .md và .txt"""
target_ext = {'.md', '.txt'}
collected = []
for base in dir_paths:
for root, _, files in os.walk(base):
for fname in files:
if Path(fname).suffix.lower() in target_ext:
collected.append(os.path.join(root, fname))
return collected
def extract_plain_text(file_paths):
"""Phân tích cú pháp và trả về danh sách Document对象"""
docs_buffer = []
for fpath in tqdm(file_paths, desc="Đang phân tích văn bản"):
ext = fpath.rsplit('.', 1)[-1]
LoaderCls = UnstructuredMarkdownLoader if ext == 'md' else UnstructuredFileLoader
try:
docs_buffer.extend(LoaderCls(fpath).load())
except Exception:
continue
return docs_buffer
SOURCE_ROUTES = [
"/root/data/InternLM", "/root/data/InternLM-XComposer",
"/root/data/lagent", "/root/data/lmdeploy",
"/root/data/opencompass", "/root/data/xtuner"
]
file_routes = scan_source_directories(SOURCE_ROUTES)
raw_documents = extract_plain_text(file_routes)
splitter_cfg = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=150)
segmented_chunks = splitter_cfg.split_documents(raw_documents)
embed_model = HuggingFaceEmbeddings(model_name="/root/data/model/sentence-transformer")
STORAGE_DIR = "data_base/vector_db/chroma"
vector_store = Chroma.from_documents(
documents=segmented_chunks,
embedding=embed_model,
persist_directory=STORAGE_DIR
)
vector_store.persist()
print("Hoàn tất xây dựng kho tri thức vectơ.")
3. Tích Hợp InternLM Vào Framework LangChain
LangChain cung cấp lớp trừu tượng LLM để chuẩn hóa interface gọi mô hình. Chúng ta kế thừa lớp này, ghi đè hàm khởi tạo và phương thức _call để kết nối trực tiếp với engine inference của InternLM:
from langchain.llms.base import LLM
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
from typing import List, Optional, Any
from langchain.callbacks.manager import CallbackManagerForLLMRun
class CustomInternLMProvider(LLM):
tok_inst: AutoTokenizer = None
mdl_inst: AutoModelForCausalLM = None
def __init__(self, ckpt_path: str):
super().__init__()
print("Đang load trọng số mô hình vào VRAM...")
self.tok_inst = AutoTokenizer.from_pretrained(ckpt_path, trust_remote_code=True)
self.mdl_inst = AutoModelForCausalLM.from_pretrained(ckpt_path, trust_remote_code=True)\
.to(torch.bfloat16).cuda().eval()
print("Khởi tạo mô hình hoàn tất.")
def _call(self, query_text: str, stop: Optional[List[str]] = None,
run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any) -> str:
sys_def = """You are an AI assistant whose name is InternLM (书生·浦语).
- InternLM (书生·浦语) is a conversational language model that is developed by Shanghai AI Laboratory (上海人工智能实验室). It is designed to be helpful, honest, and harmless.
- InternLM (书生·浦语) can understand and communicate fluently in the language chosen by the user such as English and 中文.
"""
hist_pair = [(sys_def, '')]
reply_content, _ = self.mdl_inst.chat(self.tok_inst, query_text, history=hist_pair)
return reply_content
@property
def _llm_type(self) -> str:
return "internlm_custom_wrapper"
4. Thiết Lập Chuỗi Truy Vấn Dựa Trên RAG
Mô hình RAG (Retrieval-Augmented Generation) kết hợp khả năng suy luận với thông tin thực tế từ vectơ database. Nạp lại cơ sở dữ liệu đã lưu:
from langchain.vectorstores import Chroma
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
vec_embed = HuggingFaceEmbeddings(model_name="/root/data/model/sentence-transformer")
loaded_db = Chroma(persist_directory="data_base/vector_db/chroma", embedding_function=vec_embed)
Định nghĩa template prompt bằng tiếng Việt để điều hướng phản hồi, đi kèm biến context và question:
from langchain.prompts import PromptTemplate
rag_instr = """Dựa trên ngữ cảnh được cung cấp, hãy trả lời câu hỏi bên dưới. Nếu thông tin thiếu, hãy thẳng thắn nói không biết. Luôn trả lời bằng tiếng Việt.
Câu hỏi: {question}
Ngữ cảnh tham khảo:
---
{context}
---
Câu trả lời:"""
prompt_obj = PromptTemplate(input_variables=["context", "question"], template=rag_instr)
Ghép nối LVM tùy chỉnh với bộ truy vấn vectơ:
from langchain.chains import RetrievalQA
llm_core = CustomInternLMProvider("/root/data/model/Shanghai_AI_Laboratory/internlm-chat-7b")
search_pipeline = RetrievalQA.from_chain_type(
llm=llm_core,
retriever=loaded_db.as_retriever(),
return_source_documents=True,
chain_type_kwargs={"prompt": prompt_obj}
)
test_q = "Làm thế nào để tinh chỉnh mô hình lớn?"
rag_resp = search_pipeline({"query": test_q})
print(f"[RAG Result]: {rag_resp['result']}")
direct_resp = llm_core(test_q)
print(f"[Baseline LLM]: {direct_resp}")
5. Triển Khai Ứng Dụng Giao Diện Web Với Gradio
Đóng gói logic RAG thành hàm khởi tạo đơn lẻ để tối ưu bộ nhớ, sau đó xây dựng giao diện chatbot trực quan:
import gradio as gr
from langchain.chains import RetrievalQA
from langchain.vectorstores import Chroma
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
from langchain.prompts import PromptTemplate
def build_rag_application():
emb_layer = HuggingFaceEmbeddings(model_name="/root/data/model/sentence-transformer")
store_loader = Chroma(persist_directory="data_base/vector_db/chroma", embedding_function=emb_layer)
model_engine = CustomInternLMProvider("/root/data/model/Shanghai_AI_Laboratory/internlm-chat-7b")
iface_prompt = PromptTemplate(
input_variables=["context", "question"],
template="""Trả lời dựa trên ngữ cảnh dưới đây. Giữ câu trả lời súc tích và lịch sự. Luôn kết thúc bằng 'Cảm ơn bạn đã trao đổi!'.\n{context}\nCâu hỏi: {question}\nTrả lời:"""
)
return RetrievalQA.from_chain_type(
llm=model_engine, retriever=store_loader.as_retriever(),
return_source_documents=True, chain_type_kwargs={"prompt": iface_prompt}
)
class SessionController:
def __init__(self):
self.workflow = build_rag_application()
def process_interaction(self, user_msg: str, chat_log: list):
if not user_msg or not user_msg.strip():
return "", chat_log
try:
full_reply = self.workflow({"query": user_msg})["result"]
chat_log.append((user_msg, full_reply))
return "", chat_log
except Exception as ex:
return str(ex), chat_log
app_ui = gr.Blocks(title="Hệ Thống Trợ Lý InternLM-RAG")
with app_ui:
gr.Markdown("<center><h1>Bảng Điều Khiển Hỏi Đáp InternLM</h1></center>")
with gr.Row():
with gr.Column(scale=4):
view_hist = gr.Chatbot(height=400, show_copy_button=True)
txt_inp = gr.Textbox(label="Nhập chỉ thị hoặc câu hỏi", placeholder="Ví dụ: Hướng dẫn cài đặt môi trường?")
send_btn = gr.Button("Gửi Phản Hồi", variant="primary")
clear_btn = gr.ClearButton(value="Reset Lịch Sử")
send_btn.click(fn=SessionController().process_interaction, inputs=[txt_inp, view_hist], outputs=[txt_inp, view_hist])
gr.Markdown("---\n*Thời gian khởi động lần đầu có thể kéo dài do thao tác tải trọng số. Vui lòng đợi hệ thống sẵn sàng.*")
app_ui.launch(server_name="0.0.0.0", share=False)