You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HuggingFace与Pinecone嵌入PDF摘要时向量无效的解决方案咨询

问题与解决方案

问题描述

处理一批已摘要的PDF文件,使用HuggingFace模型生成嵌入向量后,以原文档名称作为namespace存入Pinecone数据库时,始终触发ValueError(提示向量无效)。

错误原因分析

  1. 向量格式错误:Pinecone的upsert方法要求vectors参数为二维列表(每个子列表对应一个向量),但原代码直接传入了单个一维向量。
  2. namespace参数使用错误:upsert方法没有namespaces参数,正确指定namespace的方式是用单个字符串的namespace参数。
  3. ID类型错误:Pinecone要求ids的元素为字符串类型,原代码传入的整数i不符合要求。
  4. 重复初始化索引:循环内每次都创建pinecone.Index实例,属于冗余操作,影响效率。

修复后的完整代码

import os
from langchain.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
import pinecone

class Embedding:
    def __init__(self):
        self.embeddings = HuggingFaceEmbeddings(model_name="paraphrase-MiniLM-L6-v2")
        # 提前初始化Pinecone索引,避免循环内重复创建
        self.initialize_pinecone()
        self.index = pinecone.Index("lecture-index")

    def initialize_pinecone(self):
        pinecone.init(
            api_key="apikey",
            environment="environment",
        )

    def load_documents(self, folder_path):
        document_loader = DirectoryLoader(path=folder_path)
        documents = document_loader.load()
        return documents

    def split_documents(self, documents, chunk_size=1000, chunk_overlap=100):
        text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=chunk_size, chunk_overlap=chunk_overlap
        )
        split_docs = text_splitter.split_documents(documents)
        return split_docs

    def embed(self):
        print("\n-------EMBEDDING-------")

        summarizedTextsPath = os.path.join(os.path.dirname(__file__), "summarizedTexts")
        summarizedDocs = self.load_documents(summarizedTextsPath)
        summarizedDocsSplit = self.split_documents(summarizedDocs)

        # 批量处理优化,避免单次upsert效率低下
        batch_size = 100
        for batch_start in range(0, len(summarizedDocsSplit), batch_size):
            batch_end = min(batch_start + batch_size, len(summarizedDocsSplit))
            batch_docs = summarizedDocsSplit[batch_start:batch_end]
            
            ids = []
            vectors = []
            namespace_map = {}
            
            for idx, doc in enumerate(batch_docs, start=batch_start):
                text = doc.page_content
                # 跳过空文本,避免生成无效向量
                if not text.strip():
                    continue
                vector = self.embeddings.embed_query(text)
                doc_name = os.path.splitext(os.path.basename(doc.metadata["source"]))[0]
                # ID转为字符串类型
                doc_id = str(idx)
                ids.append(doc_id)
                vectors.append(vector)
                namespace_map[doc_id] = doc_name
            
            # 按namespace分组批量插入,同一namespace的向量一起upsert
            for ns in set(namespace_map.values()):
                ns_ids = [id for id in ids if namespace_map[id] == ns]
                ns_vectors = [vec for id, vec in zip(ids, vectors) if namespace_map[id] == ns]
                self.index.upsert(ids=ns_ids, vectors=ns_vectors, namespace=ns)

        print("Database access successful.")

关键注意事项

  • 索引维度匹配:确保Pinecone创建的索引维度与paraphrase-MiniLM-L6-v2的输出维度一致(该模型输出384维向量),否则会触发维度不匹配错误。
  • 空文本处理:添加空文本检查,避免生成无效的空向量。
  • 批量插入优化:采用批量插入替代循环单次插入,大幅提升数据写入效率。
  • namespace命名规则:Pinecone的namespace名称不能包含特殊字符,需确保文档名称符合要求。

内容的提问来源于stack exchange,提问作者lucasgoddamn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 23:15:18