Jina生态有两个重要的组成成分:Jina结构本身,以及数据形式DocArray。
Jina的基本结构包含三部分:Flow,Executor,还有客户端Client,理解他们之间的交互关系很重要。
DocArray是Jina的数据形式,实现多模态数据处理的重要环节。本次task熟悉了文本,图像及视频三种形式的DocArray的处理。
Jina可以帮助用户快速处理多模态数据,轻松打造多模态AI应用。
Jina 可以帮助你快速把非结构化数据例如图像,文档视频等,转换为向量数据。并结合 Jina 的其他组件设计,帮助你快速的把向量数据利用起来,实现多模态的数据搜索。
针对多模态数据的搜索难题,Jina 将深度学习和向量索引结合起来,提供了全链路的解决方案,去帮助开发者去应对神经搜索系统的三大挑战。
神经搜索指借助深度学习技术,使用非结构化数据搜索非结构化数据。
具体的介绍可以看这个文档:Jina介绍
Jina需要python3.7以上的版本,目前推荐使用python3.9。
由于在上一个任务中配置环境时已经在本地环境中完成了Jina的配置,此处跳过。若需单独配置Jina可以参考其docs
Document、Executor 和 Flow 是 Jina 的三个基本概念,分别代表数据类型,算法单元,和工作流。
了解Jina的使用,首先需要理解主要的构成,下图来源于:Basic Concepts - Jina 3.11.1 documentation
由两个实体的成分部分组成:
同时需要实现Client和Flow交互的传输数据的网络协议,具体为gRPC,通过一个YAML文件来定义。
此处教程提供了一个toycode,帮助理解Jina的基本使用流程。
VCED项目的code/jina_demo里头提供了对应的toycode文件。
执行时,首先启动gRPC服务
jina flow --uses toy.yml
启动成功如下图所示
随后启动客户端,本地的话新建一个命令行,执行
python client.py
会输出
['', 'foo was here', 'bar was here']
整个逻辑简略制图如下(丑但凑合看吧):
在快速开始中的test.py里,我们定义了两个Executor。
并且在toy.yml中用YAML文件把Flow和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)
# 通过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 分开有以下优点:
DocArray 是用于存储非结构化数据的数据结构工具包,是做跨模态应用的基础。官方文档提供了非常详细的说明:官方文档
DocArray 的亮点在于 Hierarchy + Nested。DocArray 有不同的层级结构,分层存储,第一层可以是一个整体的视频,第二层是该视频的不同镜头,第三层可以是镜头的某一帧。也可以是其他模态,比如第四层存储台词段落,第五层存储 … 既可以通过某个画面的描述搜索,也可以通过台词的意思去搜索,这样搜索的颗粒度,结构的多样性和结果的丰富度,都比传统文本检索好很多。
此外,DocArray 的设计对于 Python 用户来说非常直观,不需要学习新的语法。它融合了 Json、Pandas、Numpy、Protobuf 的优点,更适用于数据科学家和深度学习工程师。
DocArray 由三个简单的概念组成:
demo代码在VCED项目的code/jina_demo/text
里头。
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()
运行效果如下:切成了三段,分割符是半角的感叹号,而原句中是既有半角感叹号也有全角感叹号的。
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 相似性分数
demo代码在VCED项目的code/jina_demo/image
里头,就不一一贴了。
可以实现
demo代码在VCED项目的code/jina_demo/video
里头,就不一一贴了。
可以实现
load_uri_to_video_tensor
,得到的是四维数组,相比图像多出来的是帧。only_keyframes
save_video_tensor_to_file
进行视频的保存