自定义HuggingFace嵌入接入FAISS报错,寻求解决方案
问题原因与解决方案
错误原因
你调用FAISS.from_texts时传入的embeddings是AutoModel直接输出的张量结果,但LangChain的FAISS.from_texts要求第二个参数必须是LangChain封装的Embeddings类实例(这类实例自带embed_document等标准接口方法),直接传张量自然会触发no attribute embed_document错误。
解决方案
不需要从零构建FAISS,有两种简单的解决方式:
方案1:用LangChain现成的封装类(推荐)
LangChain已经为Instructor系列模型提供了HuggingFaceInstructEmbeddings封装,直接用它就能适配FAISS.from_texts的参数要求,代码如下:
# 替换你手动加载模型的代码段 from langchain_community.embeddings import HuggingFaceInstructEmbeddings # 初始化本地Instructor-XL嵌入模型 embeddings = HuggingFaceInstructEmbeddings( model_name="instructor_xl", # 你的本地模型路径 model_kwargs={"device": device} # 指定运行设备,如"cuda"或"cpu" ) # 直接生成FAISS向量库 VectorStore = FAISS.from_texts(chunks, embeddings)
这个方案无需手动处理tokenization、嵌入池化等细节,LangChain会自动完成所有适配工作。
方案2:手动生成嵌入后构建FAISS(不推荐,仅特殊场景使用)
如果一定要自己用AutoTokenizer和AutoModel生成嵌入,需要先把张量转换成numpy数组,再手动构建FAISS索引:
# 你的原有嵌入生成逻辑(补充池化和格式转换) path = "instructor_xl" tokenizer = AutoTokenizer.from_pretrained(path) model = AutoModel.from_pretrained(path).to(device) # 处理文本并生成嵌入(采用Instructor模型推荐的均值池化) token_texts = tokenizer( chunks, return_tensors="pt", padding=True, truncation=True, max_length=512 ).to(device) with torch.no_grad(): outputs = model(**token_texts) # 取最后一层隐藏状态的均值作为最终嵌入,转成numpy数组 embeddings = outputs.last_hidden_state.mean(dim=1).cpu().numpy() # 手动构建FAISS索引并适配LangChain的FAISS类 import faiss # 创建L2距离索引,维度对应Instructor-XL的768维嵌入 index = faiss.IndexFlatL2(768) index.add(embeddings) # 包装成LangChain可识别的FAISS向量库 from langchain_community.vectorstores import FAISS VectorStore = FAISS( embedding_function=None, # 手动生成嵌入后可留空 index=index, texts=chunks, docstore=None, index_to_docstore_id={i:i for i in range(len(chunks))} )
这种方式需要手动处理大量细节,仅适合需要自定义嵌入逻辑的场景。
内容的提问来源于stack exchange,提问作者CartyJ
相关产品推荐
相关产品推荐

