问题验证
- 我已经在文档和discord上寻找答案。
问题
当我尝试使用SentenceWindowNodeParser运行一个摄取管道时,我得到了以下错误:Traceback (most recent call last): File "/home/ubuntu/projects/wimi/src/llama_index/ingest_sentence_window.py", line 38, in <module> pipeline.run(documents=documents, num_workers=4) File "/home/ubuntu/miniconda3/envs/wimi/lib/python3.10/site-packages/llama_index/core/ingestion/pipeline.py", line 738, in run nodes_parallel = p.starmap( File "/home/ubuntu/miniconda3/envs/wimi/lib/python3.10/multiprocessing/pool.py", line 375, in starmap return self._map_async(func, iterable, starmapstar, chunksize).get() File "/home/ubuntu/miniconda3/envs/wimi/lib/python3.10/multiprocessing/pool.py", line 774, in get raise self._value File "/home/ubuntu/miniconda3/envs/wimi/lib/python3.10/multiprocessing/pool.py", line 540, in _handle_tasks put(task) File "/home/ubuntu/miniconda3/envs/wimi/lib/python3.10/multiprocessing/connection.py", line 206, in send self._send_bytes(_ForkingPickler.dumps(obj)) File "/home/ubuntu/miniconda3/envs/wimi/lib/python3.10/multiprocessing/reduction.py", line 51, in dumps cls(buf, protocol).dump(obj) AttributeError: Can't pickle local object 'split_by_sentence_tokenizer.<locals>.split'
代码(我实现了一个自定义读取器,返回list[Document]):
from qdrant_client import QdrantClient
from llama_index.vector_stores.qdrant import QdrantVectorStore
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.ingestion import IngestionPipeline
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from wimi_commons.llama_index.documents import JSONReader, DummyTextCleaner
from pathlib import Path
DATA_DIR = str(Path(__file__).parents[2] / "data")
if __name__=="__main__":
client = QdrantClient(host="localhost", grpc_port=6334, prefer_grpc=True)
vector_store = QdrantVectorStore(client=client, collection_name="intfloat-multilingual-e5-large-collection-llama-index-sentence-window")
embed_model = HuggingFaceEmbedding(model_name="intfloat/multilingual-e5-large")
documents =JSONReader(
file_path=f"{DATA_DIR}/solr_with_content_llama_index.json",
content_key="text"
).load_data()
node_parser = SentenceWindowNodeParser.from_defaults(
window_size=3,
window_metadata_key="window",
original_text_metadata_key="original_text",
)
pipeline = IngestionPipeline(
transformations=[
SentenceSplitter(chunk_size=2000, chunk_overlap=0),
node_parser,
embed_model,
],
vector_store=vector_store,
)
pipeline.run(documents=documents, num_workers=4)
pipeline.persist(f"{DATA_DIR}/pipeline_storage")
我不知道我在这里做错了什么...有什么建议吗?
4条答案
按热度按时间polkgigr1#
嘿 @Steinkreis,很高兴看到你回来!希望你那边一切都好。
你遇到的错误
AttributeError: "Can't pickle local object 'split_by_sentence_tokenizer.<locals>.split'"
,通常发生在Python的pickle
模块尝试序列化(pickle)一个在函数内定义的对象或是一个lambda函数时。这些局部对象无法被pickle,因为它们不在它们的模块的顶层可访问,因此它们的定义无法被pickle
序列化。在LlamaIndex仓库的
SentenceWindowNodeParser
类的上下文中,这个问题可能源于sentence_splitter
如何设置。sentence_splitter
是一个默认为split_by_sentence_tokenizer
的可调用对象,而split_by_sentence_tokenizer
似乎是一个返回另一个函数(或者是一个包含局部函数的函数)的函数。如果split_by_sentence_tokenizer
或它返回的函数使用局部函数,这些无法被pickle,这对于在摄取管道中经常使用的多进程或分布式计算任务是必要的。要解决这个问题,确保作为
sentence_splitter
传递或由split_by_sentence_tokenizer
返回的任何函数不包含局部函数或lambda表达式。相反,在模块级别定义任何所需的函数。如果split_by_sentence_tokenizer
确实返回了一个包含本地定义的函数,你需要将其重构以避免这种模式。由于没有
split_by_sentence_tokenizer
的具体实现,我无法提供一个具体的解决方案,但一般的思路是确保参与sentence_splitter
的所有函数都在模块的顶层定义,而不是作为另一个函数内的局部函数。希望这对你有所帮助!如果你有任何进一步的问题或需要更多的澄清,请随时提问。
来源
关于Dosu
这个响应旨在帮助你节省时间并提高效率。它不是精确的解决方案,而只是一个起点供你自己研究。
帮助我变得更有用!如果你觉得这个回答有帮助,请留下一个👍;如果无关紧要,请留下一个👎。
如果你想继续讨论,请用@dosu-bot开始你的回复。
x7rlezfr2#
@Steinkreis@logan-markewich 我遇到了一个类似的问题,但是是关于SemanticSplitterNodeParser的。这个问题会得到解决吗?我有一个很好的Stack Overflow链接,提到了如何处理局部函数。也许可以实现这个功能。https://stackoverflow.com/questions/72766345/attributeerror-cant-pickle-local-object-in-multiprocessing/72776044#72776044
du7egjpx3#
@ksjadeja 我当然欢迎PR。
7qhs6swi4#
@logan-markewich ,我愿意为此工作。然而,我不确定这是否是SemanticSplitterNodeParser失败的唯一原因。从错误来看,似乎局部函数是唯一的问题,我愿意提交这个更改。另外,我应该为这个PR打开一个新的问题,还是在这里更新现有的问题?