查看原文
其他

系列教程 | 用Jina搭建PDF搜索引擎Part 2

Jina AI 2023-03-21

上一篇文章我们研究了如何将PDF文件分解为可用的块,以便构建一个搜索引擎。

本文将讲解获取块同时:1、使用 CLIP 模型将它们编码为 embedding 向量。2、将它们存储在索引中以便于搜索。

对句子进行编码

通过对块进行编码,将它们转换为模型(本例中为 CLIP)可以理解的内容。虽然许多模型是单模态的(即只处理一种类型的数据,如文本、图像或音频),但 CLIP 是多模态的,这意味着它可以将不同类型数据的特征映射到相同的向量空间中,以便于可以直接计算不同模态数据间的相关性。
我们可以搜索图像到图像,文本到图像,图像到文本或文本到文本等。

1

Jina Hub针对只搜索一种类型模态的型号:

文本:
TransformerTorchEncoder,TransformerSentenceEncoder,SpacyTextEncoder
图片来源:ImageTorchEncoder

添加编码器执行器

1

以前的流程

1、提取文本段落和图像。2、将文本进行分句。3、为内容整洁,将所有文本块移动到同一级别。4、对图像进行预处理,准备编码。代码如下(包括将PDF加载到DocumentArray等):
from docarray import DocumentArrayfrom executors import ChunkSentencizer, ChunkMerger, ImageNormalizerfrom jina import Flow
docs = DocumentArray.from_files("data/*.pdf", recursive=True)
flow = (    Flow()    .add(uses="jinahub+sandbox://PDFSegmenter", name="segmenter")    .add(uses=ChunkSentencizer, name="chunk_sentencizer")    .add(uses=ChunkMerger, name="chunk_merger")    .add(uses=ImageNormalizer, name="image_normalizer")    
with flow:  indexed_docs = flow.index(docs)

2

现在的流程

只添加 CLIPEncoder ,或直接从Jina Hub添加此执行器,不用担心如何手动集成模型。在沙盒中执行操作,不用担心需要手动计算:
from docarray import DocumentArrayfrom executors import ChunkSentencizer, ChunkMerger, ImageNormalizerfrom jina import Flow
docs = DocumentArray.from_files("data/*.pdf", recursive=True)
flow = (    Flow()    .add(uses="jinahub+sandbox://PDFSegmenter", name="segmenter")    .add(uses=ChunkSentencizer, name="chunk_sentencizer")    .add(uses=ChunkMerger, name="chunk_merger")    .add(uses=ImageNormalizer, name="image_normalizer")    .add(uses="jinahub+sandbox://CLIPEncoder", name="encoder"))
with flow:  indexed_docs = flow.index(docs)
运行 Flow,查看有关以下内容的一些摘要信息可知:
1、顶级文档。2、顶级文档的每个块级别(即图像和句子)。

失败情况分析

1

失败情况概览

1、错误,如:
encoder/rep-0@113300[E]:UnidentifiedImageError(‘cannot identify image file <_io.BytesIO object at 0x7fdc143e9810>’)2、summaries 里没有embedding的内容。

2

失败原因

1、我们只用到了第一层(top-level)的Document,句子和图存在了chunks里(是第二层及以后了),所以top-level的embedding是空的,实际要用的是在chunks里的句子和图。2、如果直接将用clipencoder用在了top-level的Document,也就是整个PDF文件上,它会直接把整个pdf当做了图来进行处理。

3

解决方案

添加traversal_path参数,从而能在嵌套结构中进行搜索,同时避免处理了原先top-level的PDF整体。
flow = (    Flow()    .add(uses="jinahub+sandbox://PDFSegmenter", name="segmenter")    .add(uses=ChunkSentencizer, name="chunk_sentencizer")    .add(uses=ChunkMerger, name="chunk_merger")    .add(uses=ImageNormalizer, name="image_normalizer")    .add(        uses="jinahub+sandbox://CLIPEncoder",        name="encoder",        uses_with={"traversal_paths": "@c"},    ))
其中"@c"是遍历第一级区块,"@cc":遍历第二级块......;"@c,cc"是遍历第一级和第二级块;[...]是遍历所有块。语法详细使用说明通过以下链接或点击阅读原文访问。https://docarray.jina.ai/fundamentals/documentarray/access-elements/#index-by-nested-structure
此时,输入一个句子,可以获得匹配的段落。

由于本文处理的 PDF (即句子或图像)中只有一个级别的块,因此可以继续应用"@c"
再次运行 Flow 并检查输出:
with flow:    indexed_docs = flow.index(docs, show_progress=True)
# See summary of indexed Documentsindexed_docs.summary()
# See summary of all the chunks of indexed Documentsindexed_docs[0].chunks.summary()

将块存储在索引中

如果不将块和嵌入存储在索引中,程序退出时,他们无法自动存储。
在本文例子中,我们将使用 SimpleIndexer ,因为只是构建基础知识。
在实际应用中,还可以使用 Weaviate 或 Qdrant 后端,或来自Jina Hub的其他效率更高的索引器(如 AnnLiteIndexer )。
需要注意的一点是:我们需要牢记块级别,因此将添加一个参数:traversal_right
flow = ( Flow() .add(uses="jinahub+sandbox://PDFSegmenter", name="segmenter") .add(uses=ChunkSentencizer, name="chunk_sentencizer") .add(uses=ChunkMerger, name="chunk_merger") .add(uses=ImageNormalizer, name="image_normalizer") .add( uses="jinahub+sandbox://CLIPEncoder", name="encoder", uses_with={"traversal_paths": "@c"}, ) .add( uses="jinahub://SimpleIndexer", install_requirements=True, name="indexer", uses_with={"traversal_right": "@c"}, ))

1

运行情况

当运行 Flow 时,我们将在磁盘上看到一个文件夹。继续运行文件夹可以看到结构:workspacetree workspace

workspace

└── SimpleIndexer    

       └── 0        

              └── index.db


2 directories, 1 file

可以看到这只是一个 SQLite 文件:file workspace/SimpleIndexer/0/index.db。

它只使用 DocArray SQLite 文档存储。需要时可以直接使用磁盘加载,更加方便易行。

下期将更新第三部分,敬请期待!

参考文献:1、DocArray 0.13.17 documentation (jina.ai)2、Jina 3.4.10 documentation3、Jina Hub

神经搜索、深度学习、推荐系统


教程、Demo、干货分享


扫码备注加入讨论组

往期链接

系列教程 | 用Jina搭建PDF搜索引擎Part 1


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存