Jina 是一个 MLOps 框架,赋能开发者在云上构建多模态、跨模态的应用程序。Jina 能够将 PoC 提升为生产就绪服务。基础设施的复杂性交给 Jina,开发者能够直接轻松使用高级解决方案和云原生技术。
🌟 GitHub
https://github.com/jina-ai/jina/releases/tag/v3.14.0
本次更新包含 11 个新增功能、6 个性能改进、 12 个 错误修复以及 10 个文档改进。
🆕 新功能
Deployment 层将 Executors 重塑为独立服务(#5563, #5590, #5628, #5672 和 #5673)
Jina 3.14 旨在通过解锁更多用例,构建高性能、可扩展的服务。Jina 内置的抽象层可以用户构建可扩展、容器化的云原生组件,即 Executor。Executor 是服务,Flow 能够将多个 Executor 连接起来,协调成流水线。
Jina 3.14 允许用户在不需要 Flow 的情况下单独部署 Executor,无论是用于模型推理、预测、嵌入、生成还是搜索,Executor 都可以包装你的业务逻辑,同时提供具备云原生特性(分片、可复用、动态批处理等)的微服务 gRPC。
为了实现此功能,Jina 3.14 提供了 Deployment 层方便用户部署 Executor。与一个 Flow 组合和协调多个 Executor 不同,一个 Deployment 只能协调一个 Deployment 。Deployment 可以和 Python API 和 YAML 文件一起使用,例如,定义 Executor 后,使用 Deployment 类为系统提供服务。
from jina import Deployment
with Deployment(uses=MyExecutor, port=12345, replicas=2) as dep:
dep.block() # serve forever
─────────────────────── 🎉 Deployment is ready to serve! ───────────────────────
╭────────────── 🔗 Endpoint ────────────────╮
│ ⛓ Protocol GRPC │
│ 🏠 Local 0.0.0.0:12345 │
│ 🔒 Private 192.168.3.147:12345 │
│ 🌍 Public 87.191.159.105:12345 │
╰───────────────────────────────────────────╯
或者使用 YAML 文件实现 Deployment ,并利用 CLI 运行它:
jtype: Deployment
with:
port: 12345
replicas: 2
uses: MyExecutor
py_modules:
- my_executor.py
jina deployment --uses deployment.yml
Deployment 类提供了与 Flow 相同的接口,因此也可以用作客户端:
from jina import Deployment
with Deployment(uses=MyExecutor, port=12345, replicas=2) as dep:
docs = dep.post(on='/foo', inputs=DocumentArray.empty(1)
print(docs.texts)
此外,你可以使用 Deployment 创建 Kubernetes 和 Docker Compose YAML 配置文件,部署单个 Executor。此时,可以使用 Python API 将 Deployment 导出到 Kubernetes:
dep = Deployment(uses='jinaai+docker://jina-ai/DummyHubExecutor', port_expose=8080, replicas=3)
dep.to_kubernetes_yaml('/tmp/config_out_folder', k8s_namespace='my-namespace')
使用 CLI 将 Deployment 导出到 Kubernetes 也同样简单:
jina export kubernetes deployment.yml output\_path
使用 Python API 将 Deployment 导出到 Docker Compose:
from jina import Deployment
dep = Deployment(uses='jinaai+docker://jina-ai/DummyHubExecutor', port_expose=8080, replicas=3)
dep.to_docker_compose_yaml(
output_path='/tmp/docker-compose.yml',
)
当然,你也可以使用 CLI 将 Deployment 导出到 Docker Compose:
jina export docker-compose deployment.yml output_path
如果想了解更多关于 Executor 独立服务的详细信息,请阅读我们的文档。
https://docs.jina.ai/concepts/executor/serve/
支持 DocArray v2(Beta) (#5603)
随着 DocArray 功能的不断完善,我们决定在 Jina 中集成 DocArray 初始支持。尽管它目前还处于试验阶段,但是 DoccArray v2 提供了很好的抽象,使得用户能够清晰定义自己的服务数据。尤其是在 Jina 3.14 中引入了单个 Executor 的部署方案之后,定义服务数据变得更加方便。
此功能让你能够基于 DocArray v2 定义输入输出格式,并使用类型提示定义每个终端的模式:
from jina import Executor, requests
from docarray import BaseDocument, DocumentArray
from docarray.typing import AnyTensor, ImageUrl
class InputDoc(BaseDocument):
img: ImageUrl
class OutputDoc(BaseDocument):
embedding: AnyTensor
class MyExec(Executor):
@requests(on='/bar')
def bar(
self, docs: DocumentArray[InputDoc], **kwargs
) -> DocumentArray[OutputDoc]:
return_docs = DocumentArray[OutputDoc](
[OutputDoc(embedding=embed(doc.img)) for doc in docs]
)
return return_docs
更多关于集成 DocArarry 的信息,请阅读我们的文档。
https://docs.jina.ai/concepts/executor/docarray-v2/
在自定义的 Gateway 中与独立 Executor 通信 (#5558)
在 Jina 3.14 中,自定义 Gateway 不需要遵循 Flow 拓扑结构,就能单独调用特定的 Executor。此功能针对的是一组不同的用例,任务不一定需要由 DAG 管道定义。你可以通过显式调用 Executor 来定义处理顺序,实现中央服务(网关)与远程服务(Executor)的通信。
例如,你可以通过以下代码实现一个网关:
from jina.serve.runtimes.gateway.http.fastapi import FastAPIBaseGateway
from jina import Document, DocumentArray, Flow, Executor, requests
from fastapi import FastAPI
class MyGateway(FastAPIBaseGateway):
@property
def app(self):
app = FastAPI()
@app.get("/endpoint")
async def get(text: str):
doc1 = await self.executor['executor1'].post(on='/', inputs=DocumentArray([Document(text=text)]))
doc2 = await self.executor['executor2'].post(on='/', inputs=DocumentArray([Document(text=text)]))
return {'result': doc1.texts + doc2.texts}
return app
# Add the Gateway and Executors to a Flow
flow = Flow() \\
.config_gateway(uses=MyGateway, protocol='http', port=12345) \\
.add(uses=FirstExec, name='executor1') \\
.add(uses=SecondExec, name='executor2')
更多有关调用独立 Executor 的信息,请阅读 文档。
https://docs.jina.ai/concepts/gateway/customization/#calling-an-individual-executor
向 Jina 中添加 Kubernetes secrets (#5557)
为了构建安全的应用程序,Jina 3.14 中添加了对 Kubernetes secrets 的支持,你可以通过 Kubernetes secrets 创建环境变量。
要使用此功能,请在 Python API 或 YAML 中使用 env_from_secret
参数添加 Kubernetes secrets :
from jina import Flow
f = (
Flow().add(
uses='jinaai+docker://jina-ai/DummyHubExecutor',
env_from_secret={
'SECRET_USERNAME': {'name': 'mysecret', 'key': 'username'},
'SECRET_PASSWORD': {'name': 'mysecret', 'key': 'password'},
},
)
)
f.to_kubernetes_yaml('./k8s_flow', k8s_namespace='custom-namespace')
添加 GatewayStreamer.stream()
以返回响应和 Executor 错误 (#5650)
在此之前,GatewayStreamer.stream_docs()
方法无法捕获 Gateway 中由 Executor 引发的错误。现在,你可以使用 GatewayStreamer.stream()
方法捕获此类错误。
async for docs, error in self.streamer.stream(
docs=my_da,
exec_endpoint='/',
):
if error:
# raise error
else:
# process results
更多关于此功能的信息,请阅读 文档。
https://docs.jina.ai/concepts/gateway/customization/#recovering-executor-errors
添加参数 suppress_root_logging
以移除或保留 root logging handlers (#5635)
在此版本中,我们添加了参数 suppress_root_logging
,用于抑制 root logger(根日志)消息,默认情况下,抑制根日志消息。
在此,感谢我们的社区成员 @Jake-00 对此功能的贡献,欢迎更多小伙伴加入我们的全球开发者社区!
🧑🤝🧑 全球社区: https://slack.jina.ai
向 Worker and Head runtimes 中添加 gRPC 流式传输端
为了增强 Executor 的功能,我们向 Worker 和 Head runtimes 添加了 gRPC 流式传输端。这意味着 Executor 或 Head gRPC 服务器公开了与 Jina gRPC Gateway 相同的接口。因此,你可以基于 Jina gRPC 客户端与每个实体进行通信。
在 Client.post()
方法中添加了 prefetch
参数
此前,prefetch
参数只对 Gateway 可用,用于控制通过 Executor 的请求总数。但是它无法控制 Gateway(或单个 Executor Deployment 情况下的 Executor )能够接收的请求数量,因此,我们在 Client.post()
中加入了 prefetch
参数,以便控制发送和接收的请求总数。
更多信息,阅读文档
https://docs.jina.ai/concepts/client/rate-limit/
Runtimes 和 Executor 的预热(#5579)
启动 Jina 时,所有拥有与其他实体(Head 和 Gateway)的 gRPC 连接和 stub(存根)的 Jina 实体都会在就绪之前预热运行。这确保了第一次提交到 Flow 的请求延迟更低。
确保 gRPC 客户端的线程安全(#5533)
之前的版本中,由于gRPC asyncio 客户端对多线程的支持有限,因此在多个线程中使用 Jina gRPC 客户端时[1],会出现打印错误。
Jina 3.14 能够确保 gRPC 客户端的线程安全,这意味着同一个线程可以多次复用 gRPC 客户端,而不用担心被其它线程同时占用。因此,你可以在多线程中使用 gRPC 客户端,同时确保只有同一线程的 asyncio 任务才能同时访问 gRPC stub。
新增调查问卷 (#5667)
运行 Flow 时,终端上会显示一条带有调查问卷链接的消息,欢迎填写我们的调查问卷,以帮助我们改进 Jina,更好地服务于每一位开发者!
https://10sw1tcpld4.typeform.com/to/EGAEReM7
⚙️ 重构
1. 多协议网关使用单个网关流程(#5598)
在之前的版本中发布多协议网关时,需要公开单独的 gRPC 连接和 stub 协议。这样做并没有必要,因此 Jina 3.14 允许复用相同的连接和 stub 协议。
2. 移除手动删除通道资源通道资源的设置(#5633)
此版本重构了通道资源的处理方式,用户不需要手动删除通道资源,垃圾回收器会自动处理。
3. 无需在线程中运行摘要(#5632)
获取或打印 Flow 的摘要信息不再需要单独的线程,在主线程中处理即可。
4. 将 GRPCConnectionPool
封装成单独的包 (#5623)
所有 gRPC 连接池逻辑都重构成了一个单独的包,不再使用 GRPCConnectionPool
类。
5. 移除请求反转顺序(#5580)
Jina 3.14 在运行逻辑中删除了请求反转顺序。
5. 简化 get_docs_from_request
辅助函数(#5567)
本次更新简化了请求处理模块中的 get_docs_from_request
辅助函数,不再接收不必要的参数。
🐞 Bug 修复
1. 放宽protobuf版本要求(#5591)
为了更好地支持不同的运行环境,避免与 Google Colab 预安装的 protobuf 版本冲突,导致某些已安装的依赖项出现问题。我们放宽了 Jina 的 protobuf 版本要求。
2.修正从 YAML 文件中加载 Gateway 参数的配置错误(#5664 和 #5678)
在之前的版本中,从 YAML 文件中加载 Gateway 配置存在错误。主要问题是在加载配置时,某些参数不能正确传递到 Gateway runtime 。此外,其他默认 Gateway runtime 参数总是覆盖YAML 文件配置的参数。
2. 修复 cuda_visible_devices
的使用(#5654)
在此版本之前,如果 CUDA_VISIBLE_DEVICES
是通过 env
参数传递,而不是实际设置为环境变量,在 多个 GPU 上使用副本[2] 就会失败。
3. 正确使用 Executor、Gateway 和 Client 中的日志配置(#5638)
此版本统一了 Executor、Gateway 和 Client 的日志配置,并公开了配置参数。现在,你可以将日志配置传递给 Client 和 Flow ,并期望一致的行为日志记录:
from jina import Client
client = Client(log_config='./logging.json.yml')
# or with a Flow object
from jina import Flow
f = Flow(log_config='./logging.json.yml')
with f:
# the implicit client automatically uses the log_config from the Flow for consistency
f.post('/')
4. 在容器化的 Gateway 中将额外参数传递给 Gateway runtime (#5631)
在此版本之前,启动容器化的自定义 Gateway[3] 时,Jina 不会将某些参数传递给容器的入口点。这可能会破坏某些行为,例如,运行时不知道为 Gateway 提供服务的端口。Jina 3.14 已经此问题修复了这个问题。
5. 在 Flow 上下文管理器退出过程中清理 OpenTelemetry 资源 (#5619)
此版本将 OpenTelemetry 资源清除机制添加到 Client
类中,Flow 的上下文管理器会自动调用清理机制,防止内存泄露。
如果你启用了 OpenTelemetry 的 Client
,请调用 client.teardown_instrumentation()
方法以获取正确的客户端跨度。
6. 改进 gRPC NOT_FOUND
错误消息提示 (#5617)
当外部 Executor/Flow 在 API Gateway 之后(这是 JCloud 的情况)但是处于关闭状态时,DNS 会解析成功,却找不到“资源(Executor/Flow)。此时,会引发 gRPC NOT_FOUND
错误。
在此之前,Jina 无法恰当处理这个错误,输出如下所示:
这个输出并没有提示具体是哪个 Flow 的哪部分出错。
在此版本中,输出的信息会详细显示受影响的 Deployment 和地址:
ERROR gateway/rep-0/GatewayRuntime@123711 Error while [01/23/23 12:35:15]
getting responses from deployments: no Route matched
with those values
trailing_metadata=Metadata((('date', 'Mon, 23 Jan
2023 11:35:15 GMT'), ('content-length', '0'),
('x-kong-response-latency', '0'), ('server',
'kong/3.0.2')))
trailing_metadata=Metadata((('date', 'Mon, 23 Jan
2023 11:35:15 GMT'), ('content-length', '0'),
('x-kong-response-latency', '0'), ('server',
'kong/3.0.2')))
|Gateway: Connection error with deployment
`executor0` at address(es) {'blah.wolf.jina.ai'}.
Connection with {'blah.wolf.jina.ai'} succeeded, but
`executor0` was not found. Possibly `executor0` is
behind an API gateway but not reachable.
trailing_metadata=Metadata((('date', 'Mon, 23 Jan
2023 11:35:15 GMT'), ('content-length', '0'),
('x-kong-response-latency', '0'), ('server',
'kong/3.0.2')))
7. 使用 Hubble 的 mixin_hub_pull_options_parser
(#5586)
在 Jina 3.14 中, Jina 和 jina-hubble-sdk
都实现了某些 Hub 参数。这意味着如果 jina-hubble-sdk
更新了某些参数,就会存在不匹配或潜在的错误。此版本删除了这些参数,完全依赖于 jina-hubble-sdk
获取 Hubble 特定参数。
8. 禁用 Kubernetes 中的 Liveness Probe 超时,仅保留 Kubernetes 超时 (#5594)
在将 Executor 部署到 Kubernetes 时,Jina 会配置一个 Kubernetes 就绪探针[4]。探针是基于 jina ping
命令检查 Executor 的健康状况的,但健康检查同时受 Kubernetes 活性探针超时和 jina ping
命令超时的影响。此版本移除了(实际上是放宽)jina ping
命令超时,仅保留一个超时配置(它遵循 timeout_ready
),以便用户部署或加载速度较慢的 Executors。
9. 启用 Executor 和 Gateway 的 ping 超时 (#5600)
jina ping
命令可以向 Gateway 和 Executor 提交 ping 请求。之前 jina ping
命令会接收 timeout
参数,但请求并没有遵循该参数。现在,指定 timeout
参数后,当命令超过 timeout
指定的时长后, ping 请求就会失败。
10. 编辑终端配置文件,即使它并不存在 (#5597)
在之前的版本中,使用 pip
命令安装 Jina 时,安装脚本会自动尝试配置用户的终端配置文件(.bashrc
、.zshrc
、.fish
文件),以添加所需的配置。但是,如果用户的终端配置文件不存在,这个操作就会被忽略。
本次更新后,安装脚本会根据用户的环境识别所需的终端配置文件。如果终端配置文件不存在,安装脚本就自动创建配置文件。
10. 多协议网关支持监控功能 (#5570)
在此版本之前,在 Gateway 中使用多个协议[5]及 monitoring
功能会引发错误,Jina 3.14 修正了这个错误。
📗 文档改进
在 jcloud
中记录 tracing
支持 (#5688)
添加调查问卷 (#5649)
重构示例代码,添加对 OpenTelemetry 的支持 (#5656)
在 jina push
命令中记录 arm64
架构支持 (#5644)
添加 jcloud
Executor 可用性参数 (#5624)
在 Jcloud 部署示例中使用单个 GPU (#5620)
添加 Flow 上下文中异常的注意事项 (#5615)
在 jcloud
上记录 Flow 更新、重启、暂停和恢复的信息 (#5577)
在 JCloud 中记录 ephemeral
存储类型 (#5583)
在 JCloud 中使用 retain
参数记录 Executor 数据 (#5572)
🤘 贡献者
我们要感谢此版本的所有贡献者!
Yanlong Wang (@nomagick)
tarrantro (@tarrantro)
samsja (@samsja)
Alaeddine Abdessalem (@alaeddine-13)
Girish Chandrashekar (@girishc13)
Subba Reddy Veeramreddy (@subbuv26)
Alaeddine Abdessalem (@nan-wang)
Alex Cureton-Griffiths (@alexcg1)
Jake-00 (@Jake-00)
Anne Yang (@AnneYang720)
Joan Fontanals (@JoanFM)
Nikolas Pitsillos (@npitsillos)
Johannes Messner (@JohannesMessner)
Jackmin801 (@Jackmin801)
参考资料
[1]
多个线程中使用 Jina gRPC 客户端: https://github.com/grpc/grpc/issues/25364
[2]多个 GPU 上使用副本: https://docs.jina.ai/concepts/flow/scale-out/#replicate-on-multiple-gpus
[3]容器化的自定义 Gateway: https://docs.jina.ai/concepts/gateway/customization/#containerize-the-custom-gateway
[4]Kubernetes 就绪探针: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
[5]多个协议: https://docs.jina.ai/concepts/gateway/#enable-multiple-protocols
Jina AI 专注于打造针对多模态应用的 MLOps 开发运维工具,从原型设计到方案实施,再到系统的云上部署和监视,以及搜索结果的调优,Jina AI 提供了全链路的解决方案。先后发布了包括 Jina、DocArray,CLIP-as-service 等多个开源项目,在 GitHub 累计收到来自全球开发者超过 38k Star 的关注。
成立三年来,Jina AI 累计融资超 3700 万美金,连续两年登上 CB Insights 全球 AI 100 初创公司榜单。公司总部位于德国柏林,在美国硅谷,中国北京及深圳设有办公室。
更多技术文章
📖 Jina AI创始人肖涵博士解读多模态AI的范式变革
🎨 语音生成图像任务|🚀 模型微调神器Finetuner
💨 DocArray + Redis:快到飞起来的推荐系统
☁️ 像开挂一样轻松搞定多模态 AI 应用的部署和管理!
点击“阅读原文”,即刻了解 Jina