服务粉丝

我们一直在努力
当前位置:首页 > 科技 >

从神经搜索到多模态应用

日期: 来源:数据派THU收集编辑:数据派THU

本文约5400字,建议阅读10分钟

从神经搜索到多模态应用,这里的神经搜索指的是在搜索系统中用神经网络模型。

提到神经搜索就必然想到多模态数据,因为神经网络相比于传统搜索方式,其最大的优势就在于可以很方便地对不同模态的数据进行融合。


本文将从以下几个方面进行介绍:


  • 从神经搜索到多模态应用

  • 多模态数据

  • 多模态应用服务

  • Jina全家桶在DocsQA中的实践


01 从神经搜索到多模态应用


首先看一个典型的多模态数据——新闻,除了文字之外还会有图片的信息,有的新闻还会有视频的信息,它就是一个不同模态数据的混合。另外一个值得注意的是多模态数据中嵌套的结构,比如新闻有不同的段落,段落又可以拆解成句子,可以进一步去分词。


为什么这个嵌套结构对多模态数据非常重要呢?因为多模态不仅涉及不同的模态,同时它的语义需要从不同的颗粒度上去表示。所以多模态数据有两个重要的特征,一是有多个模态,二是嵌套的结构。


常见的多模态数据还包括电商中的商品,视频网站中的视频,音乐网站上的音乐等等。近几年关于多模态的研究也越来越多,例如 OpenAI 在做 DALL·E 和 CLIP 两个模型,最近在做 DALL·E2;国内包括百度、悟道都在做相关研究;国外微软、谷歌和 Facebook 也都有相关的研究。



现在越来越多研究者开始投身于多模态领域,一个主要的原因是因为 CV 和 NLP 方向的模型越来越趋向于统一,大家也就自然而然的想到是不是可以融合到一起去做。


既然多模态应用越来越火,那么我们是不是可以轻松地从零开始搭建一套完整的、生产环境可用的多模态服务?其实如果真正的从零开始搭建,最后还要在线上进行部署的话,整个过程还是非常复杂的,我们下面就来看一下会遇到哪些问题。


02 多模态数据


首先第一个问题就是拿到多模态数据之后,我们需要去表示这个多模态的数据。再回到我们刚才看的这个新闻的例子,我们可以在 python 里面简单的写一个 dataclass,定义几个 filed,一个是存储 picture 的 URL;还可以定义 title, string 类型;定义 paragraph;还会去加一个字典,去定义这些 meta 的信息,包括作者、地点等。



这个看起来也不是很复杂,我们通过一个 dataclass 就可以实现我们想要的对不同模态数据的支持,也可以有嵌套结构。


但是有了这个表示之后,我们还需要一些对数据的操作。比如有一个新闻的数据,希望对它进行向量表示的计算。例如用 CLIP 模型,第一步就是需要把这个图片先下载下来,存在本地的缓存,加载进来交给模型去做处理。这就需要写额外的代码。之后我们生成向量,又会产生向量如何存储的问题。一个方法是将向量存储在向量数据库里面,这就难免涉及到要配置向量数据库。


另一方面,开发一个多模态应用时,前期难免需要花一段时间去探索数据。这时,我们会需要检索数据,可能会用向量去看相似的数据都是什么样的,也可能用字段去做一些过滤,比如只看新京报写的一些新闻。想要实现这些功能,要么去数据库里直接查,要么直接写 for 循环,实现的效率都比较低。


此外,多模态数据中通常包含有不同模态的数据,比如视频、音频等,很多时候这些数据我们希望可以预览。此时我们都会需要自己动手实现这些预览功能。


最后我们还需要考虑到网络传输,因为在多模态的应用中,我们搭成的服务往往都是一个流水线,数据会在不同模块之间流转,此时就涉及到数据在流转过程中的网络传输效率。当然最简单的就是 json 做一个序列号,但这样的传输效率很低,整个服务的运行效率就会受到影响。



针对这些问题,我们开发了 DocArray,这是一个用于处理非结构化多模态数据的数据结构工具包。它能将各式各样非结构化数据,统一成同一种数据结构 Document。


还是通过之前新闻的例子来介绍一下 Document 类的用法。我们希望用 Document 对这个新闻进行封装。需要修改的代码只需要两步:第一步,使用 DocArray 提供的 dataclass 的封装来替代 python 原生的 dataclass;第二步,使用我们提供的多模态的数据类型替代 python 原生的数据类型。使用 Document 类表示多模态要比原来强大很多。



首先 ,Document 对不同模态的数据有更好的支持,比如,存图片的字段content_picture,之前只是存的 URL,加载时需要自己写图片下载的模块。用 Document 封装了之后,就可以自动完成这些操作,通过上图右边的部分可以看到,我们已经将这个图片的 URL 连同它对应的图片都保存了下来。



第二点,Document 对嵌套结构的提供原生支持。回到新闻表示的例子中,想要表示文章的段落结构,我们只要在定义 paragraph 的时候选择 List,再配上需要的模态类型,就可以自动将其转化成嵌套的结构。Document 还支持多层嵌套,可以非常方便地去表示不同语义颗粒度上的信息。



第三,Document 原生支持 embedding 的表示。我们用模型计算完 embedding 之后,就可以直接将其保存起来。



除此之外,Document 类还提供各种非常便捷的操作函数。例如,处理视频数据时候,经常需要抽帧,Document 原生支持抽帧操作。另外,在数据探索过程中,Document 数据类型提供预览的功能,可以直接听声音、看视频、并展示每一个嵌套结构中的信息。



Document 类还提供了 embedding 的预览,并支持不同的框架,无论是使用 pytorch,TensorFlow,还是 paddle,都可以直接把 tensor 存储在 Document 里面,直接使用在低位空间中预览向量表示。



Document 只对单个的多模态文本做封装,在实际训练或者推理的时候,经常会需要对一组 Document 进行批处理操作。因此我们定义了 DocumentArray 数据类型,开发者可以把他当成一个 List(Document) 来使用。



DocumentArray 支持 slicing。而且,DocumentArray 支持条件查询,比如下图例子中,我们要找出 modality 字段等于 D 的所有 Document。



DocumentArray 支持各种不同的向量存储方案。原生的存储方案是内存存储,方便大家做快速的数据探索。如果数据太大,可以选择放到硬盘里,用 sqlite 去做存储。除此之外,DocumentArray 支持各种不同的向量存储方案,包括 weaviate,qdrant,ElasticSearch,redis 等。我们内部也提供了一套基于 SQLite 和 HNSWlib 的向量近似索引的库 ANNLite。在不同的存储方案间选择也非常方便,只要调整 storage 的参数就可以。



Document 和 DocumentArray 原本是我们Jina框架的一部分,我们在打造框架的过程中,发现这两个数据结构在表示多模态数据方面非常有用,而且很多社区的小伙伴反馈说希望能单独的使用这两个类。所以,我们就把这两个数据结构单独的抽离出来,发布了一个软件包 DocArray。现在 DocArray 为我们的 Jina 全家桶提供最底层的数据结构,是整个框架中的通用语言。


03 多模态应用服务


解决了多模态数据的表示问题之后,下一个挑战是就是如何搭建多模态的应用服务。在搭建过程中,大家经常遇到的问题包括一下这些:


  • 搭建多模态应用离不开神经网络模型,当上线神经网络模型时,经常遇到框架版本和开发环境不一致的问题。这是通常是需要使用容器化,同时保证不同容器之间正常通信。这在工程上是一个非常有挑战性的问题。

  • 第二,因为需要对外提供服务,所以开发者往往需要自己搭建对外服务的接口。大家会使用 FastAPI,Flask 或者 GraphQL 等等,有时下游服务还可能要求用 gRPC,有的用 http,这些接口都需要去开发者去适配。

  • 第三点就是因为多模态的数据和应用服务往往会涉及很多模块,每个模块对算力的要求差异非常大。因此搭建服务时通常都炫耀分布式的系统,保证不同的模块在不同的机器上运行,同时保证伸缩性,比如在计算量大的模块中使用多个副本进行并行处理。

  • 第四点,现在生产环境都是在 基于 Kubernetes 的云原生环境。如果自己去完成,则需要对常用的监控、报警等工具有一定的了解。整个过程全部搭建完成,不包括模型调优的时间,也至少需要几个星期时间。



针对这些问题,我们设计了 Jina 这套框架。在 Jina 中,我们充分考虑到分布式和容器的使用,并且专门针对云原生环境进行设计。在 Jina 实现的一套多模态服务中,我们将其称之为一个 Flow。Flow 本身构成一个星型网络,它的中间核心被称为 gateway。网络中的每一个小的模块,也可以理解为处理数据过程中的每一个步骤,被称为 Executor。Executor 放在一起就构成一个 Flow,Executor 之间靠网络通信进行数据传输。


此外,我们在设计时遵循分层的设计原则。最底层是网络的通讯;中间层负责将整个服务进行编排;最上层就是 Executor,负责业务逻辑。对于绝大部分开发者来说,只需要关注 Executor 这层即可,其他两层的服务完全交给 Jina 来处理。这里有一个概念叫 Deployment,实际上就是对应中间层。就 Deployment 对一个或者多个功能相同的 Executor 进行封装,统一和 gateway 进行沟通,提供服务伸缩性的支持。



下面来看一个用 Jina 去写 executor 的例子。在刚才用 CLIP 模型计算 embedding  的例子,其实代码唯一的变化就是使用类来取代函数。整个过程只需两步,第一步是创建一个类,继承 Executor 类;第二步是在处理数据的部分,需要加入 request 装饰器,告诉框架我们希望用这个函数去处理对应的请求。只要完成这两步,Jina 框架就可以为你的类去添加必要的 API,来保证这个类可以直接融合在 Flow 里面。



定义好 Executor 以后,就可以定义我们的系统了。比如下图中就是定义了一个简单的系统,其中包含两个 encoder,一个是对 text 进行 embedding 的计算,另外一个是对 image 进行 embedding 的计算,最后进行合并。Flow 可以通过 Jina 提供的客户端访问,也可以用 curl 之类工具直接发送请求。对外提供服务都是靠前面提到的 Gateway 来负责的,Gateway 是整个服务的中心,对外可以提供 http,Websocket,gRPC,GraphQL 中心不同的协议。




Jina 自动的生成 Open API,可以非常方便和下游开发同学进行对接联调。我们自己调试和追踪 bug 的时候,也可以使用这些接口进行一些调试。



另外一方面,我们在设计的时候考虑到代码和配置一定要分离。所以,所有 Flow 的定义都可以直接使用 yaml 配置文件。在 YAML 配置文件和 Python 代码完全等价。这样的设计可以便于开发者随时随地去修改配置,比如现在某个模块算力不足,我们希望对它进行水平扩展。如果使用配置文件,就不需要去修改代码,只需要在配置文件中添加一个变量,将 replicas 设置为 3,Jina 就会自动的将服务进行伸缩。



前面提到,深度学习模型往往依赖很复杂,尤其是上线的时候。一个解决方案就是使用容器化技术。在 Jina 如果想在 flow 调用的时候使用容器化,只需要在配置文件中使用 Jina Hub+docker 的协议前缀,就可以直接去启用容器,调用相应的服务。



关于云原生,如果你不想使用 Jina 的编排,我们同时提供在 Kubernetes 环境的一键化部署,只需要定义好自己的 Flow,就可以导出 Kubernetes 的配置文件。同时,我们已经提供诸如 Grafana,Prometheus,fluentd 等常用的接口支持。



前面提到我们有一个 Jina Hub 的协议前缀,如果想使用容器,可以使用 Jina Hub 进行发布。Jina Hub 提供大量的预制模块。比如在信息抽取工作中常用的将 PDF 文件中的文字、图片抽取出来,还有从 video 中把一些帧或者把字幕抽取出来,这些在 Jina Hub 中都可以找到。Jina Hub 的另外一个功能就是方便大家做模块的分享。比如我自己写了一个模块,过两天在另外一个项目也想使用,就可以使用 Jina Hub 进行分享。



Jina 生态中另一个比较重要的功能就是 JCloud 托管服务。在定义好一个Flow 之后,直接使用 jc deploy 就可以将服务在我们云端环境 JCloud 中进行部署。例如当本机计算资源有限,但又想跑一些比较大的 encoding 模型时,就可以使用 JCloud 在远端启一个 embedding 的服务,然后在本地进行调用。我们同时提供了监控、日志等后台。更重要的是这些都是免费的。


下图是我们的 Jina 代码仓库,欢迎大家关注。我们的初衷就是希望帮助大家节省时间,由我们去写框架性的代码,让大家可以更专注业务逻辑。


04 Jina 全家桶在 DocsQA 中的实践


最后介绍 Jina 全家桶在我们内部产品中的一个实例。


在我们内部有一个产品叫 DocsQA,它本身的初衷是因为我们社区比较大,大家会经常问一些重复的问题,为了节省时间,所以就搭建了一个 QA 系统。搭建完成以后发现这个服务非常实用,于是向所有开源软件都开放了这个服务,只需要提供 GitHub 上的文档地址,我们就可以对文档进行索引,索引完成之后你会拿到一段 HTML 的代码,插到自己的网站上面就可以得到一个 QA 的对话框;在后台我们提供一个 dashboard,可以方便开发者看 QA 的统计数据,比如哪些问题是用户经常问的,方便开发者针对性的去调整文档。



整套产品都是通过 Jina 全家桶搭建完成。下图是 Flow 的架构。其中最主要的一路召回就是通过 FAQ 去召回,背后是通过问题到问题的匹配去做召回;另外一路召回就是典型的机器阅读理解(Machine Reading Comprehension,  MRC) 召回。首先通过稀疏和稠密两种方式召回候选,然后再用 Transformer 模型把其中的答案抽取出来。值得注意的是这里的每一个节点都是一组微服务,就是前面提到的 Deployment,在实现的时候只需要去写核心的 Executor 代码,这一整套服务就可以自动启起来。图中几个空心的框框出的节点就是共享的模块。我们使用的 DPR 模型和 TransformerQA 模型,计算开销都很大,同时大部分开源网站访问量都很小,所以不太可能为每个开源网站都专门部署一个服务等待请求。我们通过 Jina 提供的共享方式,使多个服务共享 DPR 服务和 TransformerQA 服务。通过这种形式可以节省很多运维费用,也因此可以为所有开源软件免费提供服务。



在 DocsQA 背后,所有的部署也是使用 JCloud 完成,这里展示了当使用 JCloud 做部署时,只需要调用 Python 的 API 就可以完成部署。之前我们使用的是 AWS 的 EKS 服务进行部署,迁移到 JCloud 之后整个成本下降了 80% 以上,因为在 JCloud 上可以保证很多不同的服务共享 node,共享很多集群的资源。



下图是整个 DocsQA系统,网站的维护者只需要在我们的服务上面提供基础的信息,主要是代码仓的地址,系统就会自动在 JCloud 上启索引服务,对代码仓库的内容进行解析,将索引存储后,接下来会启动查询的 Flow,用于创建查询的服务。查询服务会加载之前创建的索引,并对外提供服务。文档网站上对应的 UI 组件 通过调用服务接口提供服务。整个流程非常简单,属于一个比较经典的 QA 架构。



最后是对我们目前整个开源全家桶的总结,DocArray 为大家提供了一个封装多模态数据的数据类型;Jina 帮助大家搭建一个多模态的服务应用。除此之外,还有几个组件没有时间介绍,分别是:Finetuner针对一些没有太多深度学习相关知识的开发者,提供模型微调的 SaaS 服务;Jina Now 是端到端的神经搜索方案;CLIP-as-service 是一个基于 Jina 的 embedding 服务,大家可以直接 clone 代码,启一个 embedding 服务,也可以使用 SaaS 服务。



另外推荐两个在我们社区里面比较火的项目:一个是 DALL·E Flow,另外一个是 DiscoArt。属于 AI 辅助创作的项目,两个项目都是通过 Jina 全家桶完成搭建的,可玩性非常高,欢迎大家试玩。


编辑:王菁
校对:林亦霖

相关阅读

  • 刚成立一年半,这家中心为何受到联合国青睐?

  • 文 | 《中国科学报》记者 倪思洁 高雅丽
    2月2日,第77届联合国大会主席克勒希参访可持续发展大数据国际研究中心(CBAS,以下简称研究中心)。克勒希认为,研究中心“在可持续发展目标
  • 达州大数据基地项目建设加快推进

  •   达州抢抓国家“东数西算”战略机遇,充分利用成渝国家算力枢纽节点在达州布局建设城市内部数据中心的“政策红利期”,加快建设大数据区域协同创新基地。起步就是冲刺、开
  • 字节跳动埋点成本治理实践

  • 本文约6000字,建议阅读15分钟本文介绍了在字节跳动应用的埋点成本治理实践工作。
    [ 导读 ]随着业务的发展,业务上报的埋点数据会越来越多,杂乱的埋点数据不仅会消耗计算和存储
  • “数说”回乡见闻

  •   春节假期结束了,刚刚统计出炉的两个数据让人感叹不已。一个是交通数据:春节假日七天,全国春运客流总量达到22563.8万人次,超过2亿次。按照“公共交通+自驾”的春运全口径,202
  • 沿着数字中国的大江大河,领略云上三峡

  • 长年以来,提到沿江旅行,国人脑海中浮现的画面一定是三峡。而在今天,沿着数字中国的大江大河溯源而上,也会看到一座云上三峡。郦道元在《水经注》里是这样描写三峡的“至于夏水襄

热门文章

  • OPPO k1的低价高配真实么?网友:不看不知道

  • 近日OPPO一款新机OPPO k1,摒弃了高价低配,就连自家老大哥r17都要怼一下。更是放弃了请代言人,以往的OPPO手机还没出来,各路流量小生,花样美男的代言就先来了。还有线下销售人员的
  • 一招教你手机无限制成为一台新设备

  • 大家平时用手机去注册app,肯定会遇到检测设备异常,交易关闭,等问题 这个都是手机已经不止1-2次注册过此app,不断更换手机仅是一个暂时的方法,却不是长久之计,手机总归会用完
  • 从零开始如何开网店

  • 随着互联网的高速发展,人们的生活发生了翻天覆地的变化,生活节奏越来越快,网购已经成为家家户户生活中离不开的一种购物方式了。网购的发展使得越来越多的人想要涉足电商事业,那

最新文章

  • 从神经搜索到多模态应用

  • 本文约5400字,建议阅读10分钟从神经搜索到多模态应用,这里的神经搜索指的是在搜索系统中用神经网络模型。提到神经搜索就必然想到多模态数据,因为神经网络相比于传统搜索方式,其
  • 铜仁市思南县最新人事

  • 铜仁市思南县第十八届人民代表大会第二次会议公告思南县第十八届人民代表大会第二次会议于2023年2月4日选举滕建益同志为思南县监察委员会主任。现予公告思南县第十八届人民
  • 今日元宵|喜气盈庭,花好月圆事事圆

  • 花街灯如昼,月圆人团圆今天是农历正月十五我们迎来元宵节 自此良宵,大地春回癸卯春节画上了圆满的句号 今年是疫情放开后的第一个春节有人说,这个春节熟悉的年味终于回来了游