73 lines
2.4 KiB
Python
73 lines
2.4 KiB
Python
# pip install chroma
|
|
# pip install -U langchain-chroma
|
|
|
|
import os
|
|
from langchain_community.document_loaders import TextLoader
|
|
from langchain_text_splitters import RecursiveCharacterTextSplitter
|
|
from langchain_huggingface import HuggingFaceEmbeddings
|
|
from langchain_chroma import Chroma
|
|
|
|
|
|
knowledge_base_file = "war_and_peace.txt"
|
|
# 持久化目录: Chroma会把所有数据(向量+文本+元数据)都存到这个文件夹
|
|
persist_directory = './chroma_db_war_and_peace_bge_small_en_v1.5'
|
|
embedding_model = 'BAAI/bge-small-en-v1.5' # 如果愿意等待,可以换成模型"BAAI/bge-m3",效果更好更适合长文,但下载时间也更久(2.2G)
|
|
chunk_size = 500
|
|
chunk_overlap = 75
|
|
|
|
|
|
# 检查是否已创建
|
|
if os.path.exists(persist_directory):
|
|
print(f"检测到已存在的向量数据库: {persist_directory}")
|
|
print("跳过索引构建。如需重新构建,请手动删除该目录。")
|
|
exit()
|
|
|
|
if not os.path.exists(knowledge_base_file):
|
|
print(f"错误: 知识库文件 {knowledge_base_file} 未找到。")
|
|
print("请从 https://www.gutenberg.org/ebooks/2600.txt.utf-8 下载")
|
|
print("并重命名为 war_and_peace.txt 放在当前目录。")
|
|
exit()
|
|
|
|
print('---正在构建索引---')
|
|
|
|
# 1. 加载
|
|
loader = TextLoader(knowledge_base_file,encoding='utf8')
|
|
docs = loader.load()
|
|
print('加载完成...\n')
|
|
# 2. 分割
|
|
text_splitter = RecursiveCharacterTextSplitter(
|
|
chunk_size=chunk_size,
|
|
chunk_overlap=chunk_overlap
|
|
)
|
|
splits = text_splitter.split_documents(docs)
|
|
print('分割完成...\n')
|
|
# 3. 向量化 -- 第一次运行会下载模型,预计耗时2分钟
|
|
embedding_model = HuggingFaceEmbeddings(
|
|
model_name=embedding_model,
|
|
model_kwargs={'device':'cpu'}, # 强制模型在cpu上运行
|
|
encode_kwargs={'batch_size':64} # 每次处理64个文本片段
|
|
)
|
|
print('Embedding模型加载完成...\n')
|
|
# 4. 存储
|
|
print('正在构建Chroma索引...(注:此步耗时较久,预计要3min)\n')
|
|
db = Chroma(
|
|
persist_directory=persist_directory,
|
|
embedding_function=embedding_model
|
|
)
|
|
|
|
# 分批添加切片chunks(每批不超过 5000)
|
|
batch_size = 5000 # 必须 < 5461
|
|
for i in range(0, len(splits), batch_size):
|
|
batch = splits[i:i + batch_size]
|
|
db.add_documents(batch)
|
|
print(f"已插入 {min(i + batch_size, len(splits))} / {len(splits)} 条")
|
|
|
|
|
|
print(f'✅ 索引构建完毕,共 {len(splits)} 条,已保存到 {persist_directory}')
|
|
|
|
|
|
|
|
|
|
|
|
|