本文记录了在学习02_文档QA系统的环境配置、知识点和重点
环境配置
- MarsCode中给定的部分包已经deprecated,需要换成新包
# from langchain.document_loaders import PyPDFLoader
# from langchain.document_loaders import Docx2txtLoader
# from langchain.document_loaders import TextLoader
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.document_loaders import Docx2txtLoader
from langchain_community.document_loaders import TextLoader
# from langchain.pydantic_v1 import BaseModel
from pydantic import BaseModel
- 环境变量配置(使用doubao大模型)
os.environ["OPENAI_API_KEY"] = 'xxx' # 模型api_key
os.environ["OPENAI_BASE_URL"] = 'xxx' # 调用服务器base_url
os.environ["EMBEDDING_MODELEND"] = 'xxx' # 嵌入模型的endpoint
项目框架
- 加载文档:分别使用PyPDFLoader、Docx2txtLoader、TextLoader加载pdf、docx、txt格式的文件,读取其中的文本内容,以list格式存在documents中
- 文档切割:将文本按照chunk_size、chunk_overlap进行划分
- 转向量存储:文本转向量,存储到向量数据库,这一步用到embedding模型
- 设计RetrievalQA链,包括LLM(负责Answer),retriever(负责从vector DB中找相关嵌入片,随问题一起传入LLM)
重点
- 为什么在分割文本块时要设置overlap:
- 保留上下文信息
- 减少边界重点信息的丢失
- retriever如何提取和提问最相关的嵌入片(向量之间如何比较)
- 比较向量的方式主要有两种:欧式距离和余弦相似度
- 欧式距离:两个向量在多维空间之间的直线距离,即两个向量在各个维度差的平方和的平方根。适合需要关注实际距离的比较场景。
- 余弦相似度:更关注向量的方向,而不是它们的大小。即使两个向量的长度不同,只要它们的方向相似,余弦相似度也会很高。适合于文本处理等需要关注语义的场景,比如判断两个文本的相似度。
- 如何用doubao-embedding模型进行向量分析
- 创建一个新的模型推理点
- 选择Doubao-embedding|text-240715模型
- 将模型endpoint配置到环境变量中
os.environ["EMBEDDING_MODELEND"] = 'xxx'
- 通过将chunk_documents通过embedding-model转化为向量集,存储到Qdrant DB
vectorstore = Qdrant.from_documents(
documents=chunked_documents, # 以分块的文档
embedding=DoubaoEmbeddings(
model=os.environ["EMBEDDING_MODELEND"],
), # 用Doubao的Embedding Model做嵌入
location=":memory:", # in-memory 存储
collection_name="my_documents",
) # 指定collection_name
- 要创建一个新类DoubaoEmbeddings,指明调用模型的key和base_url,以及query方法
class DoubaoEmbeddings(BaseModel, Embeddings):
client: Ark = None
api_key: str = ""
model: str
def __init__(self, **data: Any):
super().__init__(**data)
if self.api_key == "":
self.api_key = os.environ["OPENAI_API_KEY"]
self.client = Ark(
base_url=os.environ["OPENAI_BASE_URL"],
api_key=self.api_key
)
def embed_query(self, text: str) -> List[float]:
"""
生成输入文本的 embedding.
Args:
texts (str): 要生成 embedding 的文本.
Return:
embeddings (List[float]): 输入文本的 embedding,一个浮点数值列表.
"""
embeddings = self.client.embeddings.create(model=self.model, input=text)
return embeddings.data[0].embedding
def embed_documents(self, texts: List[str]) -> List[List[float]]:
return [self.embed_query(text) for text in texts]
class Config:
arbitrary_types_allowed = True