[datawhale202211]跨模态神经搜索实践:Jina生态

结论速递

Jina生态有两个重要的组成成分:Jina结构本身,以及数据形式DocArray。
Jina的基本结构包含三部分:Flow,Executor,还有客户端Client,理解他们之间的交互关系很重要。
DocArray是Jina的数据形式,实现多模态数据处理的重要环节。本次task熟悉了文本,图像及视频三种形式的DocArray的处理。

前情提要

  1. 环境配置

目录

    • 结论速递
    • 前情提要
  • 1 Jina简介
    • 1.1 了解Jina
      • 1.1.1 什么是Jina
      • 1.1.2 Jina的安装
    • 1.2 Jina的基本结构及使用
      • 1.2.1 Jina的三个基本概念
      • 1.2.2 Jina的基本使用流程
      • 1.2.3 toycode:快速开始
      • 1.2.4 进阶使用
  • 2 DocArray
    • 2.1 DocArray简介
      • 2.1.1 定义
      • 2.1.2 基本概念
    • 2.2 多模态数据处理
      • 2.2.1 文本
      • 2.2.2 图像
      • 2.2.3 视频

1 Jina简介

1.1 了解Jina

1.1.1 什么是Jina

Jina可以帮助用户快速处理多模态数据,轻松打造多模态AI应用。

Jina 可以帮助你快速把非结构化数据例如图像,文档视频等,转换为向量数据。并结合 Jina 的其他组件设计,帮助你快速的把向量数据利用起来,实现多模态的数据搜索。

针对多模态数据的搜索难题,Jina 将深度学习和向量索引结合起来,提供了全链路的解决方案,去帮助开发者去应对神经搜索系统的三大挑战。

神经搜索指借助深度学习技术,使用非结构化数据搜索非结构化数据。

[datawhale202211]跨模态神经搜索实践:Jina生态_第1张图片

具体的介绍可以看这个文档:Jina介绍

1.1.2 Jina的安装

Jina需要python3.7以上的版本,目前推荐使用python3.9。

由于在上一个任务中配置环境时已经在本地环境中完成了Jina的配置,此处跳过。若需单独配置Jina可以参考其docs

1.2 Jina的基本结构及使用

1.2.1 Jina的三个基本概念

Document、Executor 和 Flow 是 Jina 的三个基本概念,分别代表数据类型,算法单元,和工作流。

  • Docunment:数据类型,解决非结构化数据和向量数据之间的映射
  • Executor:算法单元,在python实现中为类,实现具体的算法功能
  • Flow:工作流,把Executor串在一起,实现一系列的工作

1.2.2 Jina的基本使用流程

了解Jina的使用,首先需要理解主要的构成,下图来源于:Basic Concepts - Jina 3.11.1 documentation

[datawhale202211]跨模态神经搜索实践:Jina生态_第2张图片

由两个实体的成分部分组成:

  • Client:客户端
  • Flow:实现具体功能的工作流,其中:
    • Gateway:作为整个Flow的接口,和client交互
    • Executor:实现一个个的具体功能

同时需要实现Client和Flow交互的传输数据的网络协议,具体为gRPC,通过一个YAML文件来定义。

1.2.3 toycode:快速开始

此处教程提供了一个toycode,帮助理解Jina的基本使用流程。

VCED项目的code/jina_demo里头提供了对应的toycode文件。

  • YAML定义:toy.yml文件。
    • 定义了接口的port
    • flow当中包含的Executor,及它们来源的代码文件
  • Flow:test.py文件。定义了Executor具体的执行逻辑,都以类的形式进行定义。
  • Client:client.py文件。指定接口,及客户端输出效果

执行时,首先启动gRPC服务

jina flow --uses toy.yml

启动成功如下图所示

[datawhale202211]跨模态神经搜索实践:Jina生态_第3张图片

随后启动客户端,本地的话新建一个命令行,执行

python client.py

会输出

['', 'foo was here', 'bar was here']

整个逻辑简略制图如下(丑但凑合看吧):

[datawhale202211]跨模态神经搜索实践:Jina生态_第4张图片

1.2.4 进阶使用

在快速开始中的test.py里,我们定义了两个Executor。

[datawhale202211]跨模态神经搜索实践:Jina生态_第5张图片

并且在toy.yml中用YAML文件把Flow和Executor分开了。

[datawhale202211]跨模态神经搜索实践:Jina生态_第6张图片

下面是其他进阶的使用形式,包括:

  • Executor:可以利用request 装饰器实现的路由的功能

路由可以这么理解:类似于前后端分离的网站,前端通过 /index 这种形式对后端接口进行访问,后端程序收到请求后对其进行解析,并根据路由规则将该请求传递到指定的方法中执行。
在一个 Executor 的方法中默认可以指定 @request(on="")参数,其中 on 后面接的字符串就是该方法绑定的路由。
如果没有 on 这个参数,此时就是默认路由,当请求找不到对应的路由时会执行该方法。

from jina import Document, DocumentArray, Flow, Executor, requests

class FooExecutor(Executor):
    @requests
    def foo(self, docs: DocumentArray, **kwargs):
        docs.append(Document(text='foo was here'))

class BarExecutor(Executor):
    @requests
    def bar(self, docs: DocumentArray, **kwargs):
        docs.append(Document(text='bar was here'))

class MyExecutor(Executor):
    @requests
    def foo(self, **kwargs):
        print(kwargs)

    @requests(on='/index')
    def bar(self, **kwargs):
        print(kwargs)
  • Flow :还可以通过 add 方法可以将多个 Executor 串成一套执行逻辑。实现用纯python的方法而非YAML方式启动Flow发送请求。
# 通过add的方法串起来
f = (
    Flow()
    .add(uses=FooExecutor, name='fooExecutor')
    .add(uses=BarExecutor, name='barExecutor')
    .add(uses=MyExecutor, name='MyExecutor')
)  # 创建一个空的 Flow

with f:  # 启动 Flow
    response = f.post(
        on='/'
    ) # 向 flow 发送一个请求
    print(response.texts)

不过,快速开始中通过 YAML 方式将 Executor 和 Flow 分开有以下优点:

  • 服务器上的数据流是非阻塞和异步的,当 Executor 处于空闲状态时,会立即处理新的请求。
  • 必要时会自动添加负载平衡,以确保最大吞吐量。

2 DocArray

2.1 DocArray简介

2.1.1 定义

DocArray 是用于存储非结构化数据的数据结构工具包,是做跨模态应用的基础。官方文档提供了非常详细的说明:官方文档

DocArray 的亮点在于 Hierarchy + Nested。DocArray 有不同的层级结构,分层存储,第一层可以是一个整体的视频,第二层是该视频的不同镜头,第三层可以是镜头的某一帧。也可以是其他模态,比如第四层存储台词段落,第五层存储 … 既可以通过某个画面的描述搜索,也可以通过台词的意思去搜索,这样搜索的颗粒度,结构的多样性和结果的丰富度,都比传统文本检索好很多。
此外,DocArray 的设计对于 Python 用户来说非常直观,不需要学习新的语法。它融合了 Json、Pandas、Numpy、Protobuf 的优点,更适用于数据科学家和深度学习工程师。

2.1.2 基本概念

DocArray 由三个简单的概念组成:

  • Document:一种表示嵌套非结构化数据的数据结构,是 DocArray 的基本数据类型。规范化文本、图像、视频、音频、3D、表格 或它们的嵌套或组合的数据结构(图来源于官方文档)
    [datawhale202211]跨模态神经搜索实践:Jina生态_第7张图片

  • DocumentArray:可以保存多个 Document 的列表(图来源于官方文档 )
    [datawhale202211]跨模态神经搜索实践:Jina生态_第8张图片

  • Dataclass:用于直观表示多模式数据的高级API,官方文档提供了一个把报纸转化成数据的示意。
    [datawhale202211]跨模态神经搜索实践:Jina生态_第9张图片

2.2 多模态数据处理

2.2.1 文本

demo代码在VCED项目的code/jina_demo/text里头。

  • 创建文本:列举了两种形式,支持多语言
    1. 直接从text来
    2. 从url导入,适用于大批数据(示例里的得科学上网一下)
from jina import Document  # 导包
# 创建简单的文本数据
d = Document(text='hello, world.') # 通过text获取文本数据
# 如果文本数据很大,或者自URI,可以先定义URI,然后将文本加载到文档中
d = Document(uri='https://www.w3.org/History/19921103-hypertext/hypertext/README.html')
d.load_uri_to_text()
  • 切割文本
from jina import Document  # 导包

d = Document(text='	नमस्ते दुनिया!	你好世界!こんにちは世界!	Привет мир!')
d.chunks.extend([Document(text=c) for c in d.text.split('!')])  # 按'!'分割
d.summary()

运行效果如下:切成了三段,分割符是半角的感叹号,而原句中是既有半角感叹号也有全角感叹号的。

[datawhale202211]跨模态神经搜索实践:Jina生态_第10张图片

  • text、ndarray 互转:毕竟是向量

text转ndarray如下

from jina import DocumentArray, Document  # 导包

# DocumentArray 相当于一个 list,用于存放 Document
da = DocumentArray([Document(text='hello world'), 
                    Document(text='goodbye world'),
                    Document(text='hello goodbye')])

vocab = da.get_vocabulary()  # 输出:{'hello': 2, 'world': 3, 'goodbye': 4}

# 转为ndarray
for d in da:
    d.convert_text_to_tensor(vocab, max_length=10)  # 转为tensor向量,max_length为向量最大值,可不设置
    print(d.tensor) 

输出是

{'hello': 2, 'world': 3, 'goodbye': 4}
[0 0 0 0 0 0 0 0 2 3]
[0 0 0 0 0 0 0 0 4 3]
[0 0 0 0 0 0 0 0 2 4]

ndarray转text如下

 # ndarray转text
 for d in da:
    d.convert_tensor_to_text(vocab)
    print(d.text)

输出是

hello world
goodbye world
hello goodbye
  • 还可以实现简单的文本匹配
from jina import Document, DocumentArray

d = Document(uri='https://www.gutenberg.org/files/1342/1342-0.txt').load_uri_to_text() # 链接是傲慢与偏见的电子书,此处将电子书内容加载到 Document 中
da = DocumentArray(Document(text=s.strip()) for s in d.text.split('\n') if s.strip()) # 按照换行进行分割字符串
da.apply(lambda d: d.embed_feature_hashing())

q = (
    Document(text='she entered the room') # 要匹配的文本
    .embed_feature_hashing()  # 通过 hash 方法进行特征编码
    .match(da, limit=5, exclude_self=True, metric='jaccard', use_scipy=True) # 找到五个与输入的文本最相似的句子
)

print(q.matches[:, ('text', 'scores__jaccard')]) # 输出对应的文本与 jaccard 相似性分数

输出是
[datawhale202211]跨模态神经搜索实践:Jina生态_第11张图片

2.2.2 图像

demo代码在VCED项目的code/jina_demo/image里头,就不一一贴了。

可以实现

  • 读取图像并转为Tensor:
  • 图像处理:设置大小,标准化,更改通道等
  • 图像集的读取
  • 大型图像的切割

2.2.3 视频

demo代码在VCED项目的code/jina_demo/video里头,就不一一贴了。

可以实现

  • 视频导入和切分:load_uri_to_video_tensor,得到的是四维数组,相比图像多出来的是帧。
  • 提取关键帧:使用 only_keyframes
  • 张量转存为视频:save_video_tensor_to_file 进行视频的保存

你可能感兴趣的:(jina,python,人工智能)