【Datawhale跨模态实践学习笔记】Jina体验
一、Jina 是什么
定义
简单来说 Jina 可以帮助你快速把非结构化数据例如图像,文档视频等,转换为向量数据。并结合 Jina 的其他组件设计,帮助你快速的把向量数据利用起来,实现多模态的数据搜索。
三个基本概念
Document、Executor 和 Flow 是 Jina 的三个基本概念。
-
Document 是基本的数据类型,它的作用就是可以将非结构化数据与向量数据之间进行映射,具体细节会在 DocArray 一章中详细阐述。
-
Executor 可以理解为一个 Python 类,代表了 Jina 中的算法单元,比如把图像编码成向量、对结果进行排序等算法等都可以用 Executor 来表述。
-
Flow 可以将多个 Executor 连接起来,将他们协调成流水线(pipeline)。
二、安装 Jina
#via pypi
pip install jina
#via conda
conda install jina -c conda-forge
#via docker
docker pull jinaai/jina:latest
三、快速上手
定义toy.yaml
# toy.yml
jtype: Flow
with:
port: 51000
protocol: grpc
executors:
- uses: FooExecutor
name: foo
py_modules:
- test.py
- uses: BarExecutor
name: bar
py_modules:
- test.py
# 创建 test.py 文件与 YAML 文件在同一目录下
# 导入 document、executor 和 flow 以及 requests 装饰器
from jina import DocumentArray, Executor, requests, Document
# 编写 FooExecutor 与 BarExecutor 类,类中定义了函数 foo 和 bar
# 该函数从网络请求接收 DocumentArray (先暂时不需要理解它是什么),并在其内容后面附加 "foo was here" 与 "bar was here"
class FooExecutor(Executor):
@requests # 用于指定路由,类似网页访问 /index 和 /login 会被路由到不同的方法上是用样的概念,关于 request 下面会再进行详细介绍
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'))
运行以下命令启动 grpc 服务:
jina flow --uses toy.yml
运行结果:
然后创建 client.py 文件,执行 python client.py
# 从 Jina 中导入连接的客户端与 Document
from jina import Client, Document
c = Client(host='grpc://0.0.0.0:51000') # 如果运行提示失败,可尝试使用localhost
result = c.post('/', Document()) # 将一个空的 Document 传到服务端执行
print(result.texts)
输出结果:
['', 'foo was here', 'bar was here']
四、Docarray
定义
DocArray 是用于存储非结构化数据的数据结构工具包,是本次我们做跨模态应用的基础。通过这个小而精的入口,能友好地带你走进多模态、跨模态的世界。
DocArray 的亮点在于 Hierarchy + Nested。DocArray 有不同的层级结构,分层存储,第一层可以是一个整体的视频,第二层是该视频的不同镜头,第三层可以是镜头的某一帧。也可以是其他模态,比如第四层存储台词段落,第五层存储 … 既可以通过某个画面的描述搜索,也可以通过台词的意思去搜索,这样搜索的颗粒度,结构的多样性和结果的丰富度,都比传统文本检索好很多。
此外,DocArray 的设计对于 Python 用户来说非常直观,不需要学习新的语法。它融合了 Json、Pandas、Numpy、Protobuf 的优点,更适用于数据科学家和深度学习工程师。
三个基本概念
DocArray 由三个简单的概念组成:
-
Document:一种表示嵌套非结构化数据的数据结构,是 DocArray 的基本数据类型。无论是处理文本、图像、视频、音频、3D、表格 或它们的嵌套或组合,都可以用 Document 来表示,从而使得各类数据的结构都非常规整,方便后续处理
-
DocumentArray:用于高效访问、处理和理解多个文档的容器,可以保存多个 Document 的列表
-
Dataclass:用于直观表示多模式数据的高级API
创建文本
from jina import Document # 导包
# 创建简单的文本数据
d = Document(text='hello, world.')
print(d.text) # 通过text获取文本数据
# 如果文本数据很大,或者自URI,可以先定义URI,然后将文本加载到文档中
d = Document(uri='https://www.w3.org/History/19921103-hypertext/hypertext/README.html')
d.load_uri_to_text()
print(d.text)
# 支持多语言
d = Document(text='👋 नमस्ते दुनिया! 你好世界!こんにちは世界! Привет мир!')
print(d.text)
输出结果:
hello, world.
👋 नमस्ते दुनिया! 你好世界!こんにちは世界! Привет мир!
切割文本
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)
# ndarray
for d in da:
d.convert_tensor_to_text(vocab)
print(d.text)
输出结果:
[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]
hello world
goodbye world
hello goodbye
Demo: 简单的文本匹配
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 相似性分数
输出结果:
[['Darcy only, entered the room.', 'in the room.', 'which Elizabeth received from Jane as soon as she entered the room, and', 'She entered the room with an air more than usually ungracious, made no', 'husband, called out, as she entered the library,--'], [{'value': 0.5714285714285714}, {'value': 0.6666666666666666}, {'value': 0.6923076923076923}, {'value': 0.6923076923076923}, {'value': 0.7}]]
- 点赞
- 收藏
- 关注作者
评论(0)