人工智能大模型MLOpsLLMOps模型推理服务云原生后端【免费下载链接】seldon-coreAn MLOps framework to package, deploy, monitor and manage thousands of production machine learning models项目地址https://gitcode.com/gh_mirrors/se/seldon-core点击查看免费下载在 Seldon Core v2 中Pipeline 由多个 Model 步骤串联而成只有当 Pipeline 内的全部模型都完成加载后整条 Pipeline 才真正具备推理能力。本文基于仓库示例文档docs-gb/examples/pipeline-ready-and-metadata.md的完整操作脉络通过tfsimples两模型串联 Pipeline演示如何在本地与 Kubernetes 两种环境下逐变更检查 Pipeline 就绪状态RESTready端点、gRPCModelReadyRPC、CLI 状态轮询并结合 Gateway 与 Operator 源码说明PipelineReady/ModelsReady状态背后的判定逻辑帮助读者建立变更后即可验证的生产级部署检查能力。环境准备三种关键端点检查 Pipeline 就绪状态需要访问三类端点。原文档给出了本地local与远程 K8s 集群两套环境变量设置# 本地环境Local example settings %env INFER_REST_ENDPOINThttp://0.0.0.0:9000 %env INFER_GRPC_ENDPOINT0.0.0.0:9000 %env SELDON_SCHEDULE_HOST0.0.0.0:9004# 远程 K8s 集群示例 - change as neeed for your needs按需修改 #%env INFER_REST_ENDPOINThttp://172.19.255.1:80 #%env INFER_GRPC_ENDPOINT172.19.255.1:80 #%env SELDON_SCHEDULE_HOST172.19.255.2:9004三个变量分别对应INFER_REST_ENDPOINTPipeline Gateway 的 REST 数据平面入口用于curl调用infer/ready等 v2 端点INFER_GRPC_ENDPOINT同一 Gateway 的 gRPC 数据平面入口用于grpcurl调用inference.GRPCInferenceService/ModelReadySELDON_SCHEDULE_HOSTScheduler 控制平面默认 9004 端口seldonCLI 通过它完成 load/unload/status 等控制操作。在本地环境中通常先通过kubectl port-forward或本地 compose 配置把 Gateway 与 Scheduler 端口暴露到本机再按上述值设置环境变量。示例对象tfsimples Pipeline 与其两个模型原示例围绕 Pipelinetfsimples展开它把tfsimple1、tfsimple2两个 TensorFlow 简单模型串联并通过tensorMap把上游两个输出张量映射到下游两个输入张量。仓库中的 tfsimples.yaml 与文档内容一致cat ./pipelines/tfsimples.yamlapiVersion: mlops.seldon.io/v1alpha1 kind: Pipeline metadata: name: tfsimples spec: steps: - name: tfsimple1 - name: tfsimple2 inputs: - tfsimple1 tensorMap: tfsimple1.outputs.OUTPUT0: INPUT0 tfsimple1.outputs.OUTPUT1: INPUT1 output: steps: - tfsimple2两个模型定义见 tfsimple1.yaml 与 tfsimple2.yaml二者结构相同apiVersion: mlops.seldon.io/v1alpha1 kind: Model metadata: name: tfsimple1 spec: storageUri: gs://seldon-models/triton/simple requirements: - tensorflow memory: 100Ki注意这里storageUri指向 Google Storage 上的 Triton 格式模型requirements声明需要 tensorflow 能力memory: 100Ki是调度器用于计算资源占用的近似值。Pipeline 的steps中未写inputs的步骤tfsimple1即为入口步骤tfsimple2.inputs声明其上游为tfsimple1tensorMap完成OUTPUT0/OUTPUT1 → INPUT0/INPUT1的张量重命名。原文档的核心思路是We will check the readiness of the Pipeline after every change to model and pipeline每次对 model 或 pipeline 做变更后都检查一次就绪状态。下文按原文档的变更顺序逐步演示。变更 0尚无 Pipeline 时检查 ready —— 得到 Unimplemented/错误在任何资源加载之前先对 REST 与 gRPC 两个入口发起 ready 查询curl -Ik ${INFER_REST_ENDPOINT}/v2/pipelines/tfsimples/readygrpcurl -d {name:tfsimples} \ -plaintext \ -import-path ../apis \ -proto ../apis/mlops/v2_dataplane/v2_dataplane.proto \ -rpc-header seldon-model:tfsimples.pipeline \ ${INFER_GRPC_ENDPOINT} inference.GRPCInferenceService/ModelReadygRPC 侧返回ERROR: Code: Unimplemented Message:两个../apis相对路径是相对samples/目录的本地引用在仓库根目录下对应的 proto 文件为 v2_dataplane.proto。其中ModelReadyRPC 定义如下proto 第 31-32 行// The ModelReady API indicates if a specific model is ready for inferencing. rpc ModelReady(ModelReadyRequest) returns (ModelReadyResponse) {} message ModelReadyRequest { string name 1; // 要检查就绪状态的模型Pipeline名 string version 2; // 可选版本 } message ModelReadyResponse { bool ready 1; // true 表示就绪 }需要特别注意 gRPC 调用中的-rpc-header seldon-model:tfsimples.pipeline请求头seldon-model的值是name.pipelineGateway 依赖它把ModelReady请求识别为对Pipeline 资源的就绪查询而不是对单个 Model 的查询。这一点在 grpcserver.go 中有直接注释与实现第 180-195 行// This is presently used for pipeline ready use cases but the v2 protocol only has the concept of model ready calls func (g *GatewayGrpcServer) ModelReady(ctx context.Context, req *v2.ModelReadyRequest) (*v2.ModelReadyResponse, error) { md, ok : metadata.FromIncomingContext(ctx) if !ok { return nil, status.Errorf(codes.FailedPrecondition, failed to find any metadata - required %s or %s, util.SeldonModelHeader, util.SeldonInternalModelHeader) } ready, err : g.pipelineReadyChecker.CheckPipelineReady(ctx, req.GetName(), g.getRequestId(md)) if err ! nil { if errors.Is(err, status2.PipelineNotFoundErr) { return nil, status.Errorf(codes.NotFound, Pipeline not found) } ... } return v2.ModelReadyResponse{Ready: ready}, nil }即v2 数据平面协议里只有model ready的概念Seldon 通过seldon-model头将其复用为pipeline ready查询当资源不存在时会返回NotFoundPipeline not found。Pipeline 尚未加载时REST 与 gRPC 都会给出错误而非ready: false。变更 1加载 Pipeline此时无模型Pipeline 创建后、模型未加载前Pipeline 本身已可被控制平面接受但 ready 查询仍不会通过。两种方式使用 kubectlkubectl apply -f ./pipelines/tfsimples.yaml -n ${NAMESPACE}pipeline.mlops.seldon.io/tfsimples createdkubectl wait --for conditionready --timeout300s pipeline tfsimples -n ${NAMESPACE}使用 seldon-cliseldon pipeline load -f ./pipelines/tfsimples.yaml seldon pipeline status tfsimples -w PipelineReady{pipelineName:tfsimples, versions:[{pipeline:{name:tfsimples, uid:ciepit2i8ufs73flaitg, version:1, steps:[{name:tfsimple1}, {name:tfsimple2, inputs:[tfsimple1.outputs], tensorMap:{tfsimple1.outputs.OUTPUT0:INPUT0, tfsimple1.outputs.OUTPUT1:INPUT1}}], output:{steps:[tfsimple2.outputs]}, kubernetesMeta:{}}, state:{pipelineVersion:1, status:PipelineReady, reason:created pipeline, lastChangeTimestamp:2023-06-29T14:47:16.365934922Z}}]}-w PipelineReady阻塞等待状态机进入PipelineReady即 Pipeline 资源本身已创建。此时注意状态 JSON 中没有modelsReady字段seldon pipeline status tfsimples | jq .versions[0].state.modelsReadynull再对数据平面发起 ready 检查与变更 0 相同的两条命令curl -Ik ${INFER_REST_ENDPOINT}/v2/pipelines/tfsimples/readygrpcurl -d {name:tfsimples} \ -plaintext \ -import-path ../apis \ -proto ../apis/mlops/v2_dataplane/v2_dataplane.proto \ -rpc-header seldon-model:tfsimples.pipeline \ ${INFER_GRPC_ENDPOINT} inference.GRPCInferenceService/ModelReady{ }即此时 gRPCModelReady返回空对象模型都还不存在未返回ready: trueREST 侧也不会给出 200 就绪响应。Pipeline 存在与 Pipeline 可推理是两回事。变更 2加载第一个模型 tfsimple1使用 kubectlkubectl apply -f ./models/tfsimple1.yaml -n ${NAMESPACE} kubectl wait --for conditionready --timeout300s model tfsimple1 -n ${NAMESPACE}model.mlops.seldon.io/tfsimple1 created model.mlops.seldon.io/tfsimple1 condition met使用 seldon-cliseldon model load -f ./models/tfsimple1.yaml seldon model status tfsimple1 -w ModelAvailable{} {}加载单个模型后再次执行 ready 检查两条命令同上响应仍为{ }两个模型尚未全部就绪Pipeline 整体仍不可用——这正是 Pipeline 级就绪语义任一 step 模型未就绪则整条 Pipeline 不就绪。变更 3加载第二个模型 tfsimple2 —— Pipeline 真正就绪使用 kubectlkubectl apply -f ./models/tfsimple2.yaml -n ${NAMESPACE} kubectl wait --for conditionready --timeout300s model tfsimple2 -n ${NAMESPACE}model.mlops.seldon.io/tfsimple2 created model.mlops.seldon.io/tfsimple2 condition met使用 seldon-cliseldon model load -f ./models/tfsimple2.yaml seldon model status tfsimple2 -w ModelAvailable | jq -M .{} {}全部模型就绪后REST 检查curl -Ik ${INFER_REST_ENDPOINT}/v2/pipelines/tfsimples/readygRPC 检查grpcurl -d {name:tfsimples} \ -plaintext \ -import-path ../apis \ -proto ../apis/mlops/v2_dataplane/v2_dataplane.proto \ -rpc-header seldon-model:tfsimples.pipeline \ ${INFER_GRPC_ENDPOINT} inference.GRPCInferenceService/ModelReady{ ready: true }CLI 侧的状态也同步变为就绪seldon pipeline status tfsimples | jq .versions[0].state.modelsReadytrue源码视角PipelineReady 如何判定数据平面的 ready 判定实现于 ready.go。SimpleReadyChecker.CheckPipelineReady的逻辑非常直白取 Pipeline 状态遍历其全部Steps中的模型名逐个调用CheckModelReady只要有一个模型不就绪或查询出错整个 Pipeline 即返回不就绪全部通过才返回truefunc (s *SimpleReadyChecker) CheckPipelineReady(ctx context.Context, pipelineName string, requestId string) (bool, error) { pipeline : s.pipelineStatusGetter.Get(pipelineName) if pipeline nil { return false, PipelineNotFoundErr } for modelName : range pipeline.Steps { ready, err : s.modelReadyCaller.CheckModelReady(ctx, modelName, requestId) if err ! nil || !ready { return ready, err } } return true, nil }而 REST 入口/v2/pipelines/{name}/ready正是在 Gateway 的 HTTP 路由中注册的见 httpserver.go 第 112-125 行/v2/models/{name}/ready与/v2/pipelines/{name}/ready两条路由最终都汇聚到pipelineReady处理函数内部同样调用CheckPipelineReadyconst ( v2ModelPathPrefix /v2/models/ v2PipelinePathPrefix /v2/pipelines/ ) ... g.router.NewRoute().Path( v2ModelPathPrefix { ResourceNameVariable }/ready).HandlerFunc(g.pipelineReadyFromModelPath) g.router.NewRoute().Path( v2PipelinePathPrefix { ResourceNameVariable }/ready).HandlerFunc(g.pipelineReadyFromPipelinePath)这也解释了为什么对不存在或模型缺失的 PipelineCheckPipelineReady会走PipelineNotFoundErr或模型未就绪分支而不是返回ready: true。变更 4卸载 Pipeline —— 回到 Unimplementedseldon pipeline unload tfsimples再执行 ready 检查curl -Ik ${INFER_REST_ENDPOINT}/v2/pipelines/tfsimples/readygrpcurl -d {name:tfsimples} \ -plaintext \ -import-path ../apis \ -proto ../apis/mlops/v2_dataplane/v2_dataplane.proto \ -rpc-header seldon-model:tfsimples.pipeline \ ${INFER_GRPC_ENDPOINT} inference.GRPCInferenceService/ModelReadyERROR: Code: Unimplemented Message:但注意一个细节原文档特别指出Models will still be ready even though Pipeline terminated——即使 Pipeline 已终止模型本身依然保持就绪状态seldon pipeline status tfsimples | jq .versions[0].state.modelsReadytrue这说明modelsReady记录的是该 Pipeline 定义所引用模型的就绪事实它与 Pipeline 资源是否活跃是两个独立维度。因此重新加载 Pipeline 后无需再等待模型加载即可立刻恢复就绪seldon pipeline load -f ./pipelines/tfsimples.yaml seldon pipeline status tfsimples -w PipelineReady{pipelineName:tfsimples, versions:[{pipeline:{name:tfsimples, uid:ciepj5qi8ufs73flaiu0, version:1, steps:[{name:tfsimple1}, {name:tfsimple2, inputs:[tfsimple1.outputs], tensorMap:{tfsimple1.outputs.OUTPUT0:INPUT0, tfsimple1.outputs.OUTPUT1:INPUT1}}], output:{steps:[tfsimple2.outputs]}, kubernetesMeta:{}}, state:{pipelineVersion:1, status:PipelineReady, reason:created pipeline, lastChangeTimestamp:2023-06-29T14:47:51.626155116Z, modelsReady:true}}]}注意与变更 1 的输出对比这次状态 JSON 中多了modelsReady:true因为两个模型在卸载 Pipeline 期间一直保持着加载状态。随后验证curl -Ik ${INFER_REST_ENDPOINT}/v2/pipelines/tfsimples/readygrpcurl -d {name:tfsimples} \ -plaintext \ -import-path ../apis \ -proto ../apis/mlops/v2_dataplane/v2_dataplane.proto \ -rpc-header seldon-model:tfsimples.pipeline \ ${INFER_GRPC_ENDPOINT} inference.GRPCInferenceService/ModelReady{ ready: true }seldon pipeline status tfsimples | jq .versions[0].state.modelsReadytrue最后做清理先卸载模型再卸载 Pipelineseldon model unload tfsimple1 seldon model unload tfsimple2seldon pipeline status tfsimples | jq .versions[0].state.modelsReadynullseldon pipeline unload tfsimples模型卸载后modelsReady回到null闭环验证了modelsReady 由所引用模型的实时加载状态驱动这一结论。Kubernetes 资源视角ModelsReady Condition 的等待与排查原文档最后演示了在 Kubernetes 中直接操作 CRD 时就绪状态如何体现在 Pipeline 资源的status.conditions上。NoteSeldon CLI 允许在非 Kubernetes 环境中通过 scheduler 查看底层 Seldon 资源信息并做变更但它无法修改 Kubernetes 集群内的底层 manifests因此不推荐在 Kubernetes 环境中使用 Seldon CLI 做控制平面操作。详情参见 Seldon CLI 文档。先获取seldon-mesh服务的 LoadBalancer 入口 IPimport os os.environ[NAMESPACE] seldon-meshMESH_IP!kubectl get svc seldon-mesh -n ${NAMESPACE} -o jsonpath{.status.loadBalancer.ingress[0].ip} MESH_IPMESH_IP[0] import os os.environ[MESH_IP] MESH_IP MESH_IP172.19.255.1只创建 Pipeline、不创建模型然后等待 ready conditionkubectl create -f ./pipelines/tfsimples.yaml -n ${NAMESPACE}pipeline.mlops.seldon.io/tfsimples createdkubectl wait --for conditionready --timeout1s pipeline --all -n ${NAMESPACE}error: timed out waiting for the condition on pipelines/tfsimpleskubectl wait超时是预期行为——模型还没加载。此时查看 condition 可以明确失败原因kubectl get pipeline tfsimples -o jsonpath{.status.conditions[0]} -n ${NAMESPACE}{lastTransitionTime:2022-11-14T10:25:31Z,status:False,type:ModelsReady}ModelsReadycondition 为False说明 Pipeline 的就绪卡在模型未就绪上。加载两个模型kubectl create -f ./models/tfsimple1.yaml -n ${NAMESPACE} kubectl create -f ./models/tfsimple2.yaml -n ${NAMESPACE}model.mlops.seldon.io/tfsimple1 created model.mlops.seldon.io/tfsimple2 createdkubectl wait --for conditionready --timeout300s pipeline --all -n ${NAMESPACE}pipeline.mlops.seldon.io/tfsimples condition met再次查看 conditionModelsReady翻转为Truekubectl get pipeline tfsimples -o jsonpath{.status.conditions[0]} -n ${NAMESPACE}{lastTransitionTime:2022-11-14T10:25:49Z,status:True,type:ModelsReady}清理现场kubectl delete -f ./models/tfsimple1.yaml -n ${NAMESPACE} kubectl delete -f ./models/tfsimple2.yaml -n ${NAMESPACE} kubectl delete -f ./pipelines/tfsimples.yaml -n ${NAMESPACE}model.mlops.seldon.io tfsimple1 deleted model.mlops.seldon.io tfsimple2 deleted pipeline.mlops.seldon.io tfsimples deletedModelsReady这个 condition 类型由 Operator 的 Pipeline CRD 定义维护pipeline_types.go 中声明了ModelsReady apis.ConditionType ModelsReady并通过 kubebuilder printcolumn 把status.conditions[?(.typeModelsReady)].status暴露为kubectl get pipeline表格中的 Models ready 列可直接用于集群巡检。小结就绪检查的三层视图把原文档的操作与源码证据放在一起Seldon Core v2 对 Pipeline 就绪性提供了三层互相印证的检查手段层面检查手段观察对象适用场景数据平面 RESTcurl -Ik $INFER_REST_ENDPOINT/v2/pipelines/{name}/readyGateway 的CheckPipelineReadyhttpserver.go推理客户端/探针变更后的即时验证数据平面 gRPCgrpcurl ... ModelReady携带seldon-model:{name}.pipeline头grpcserver.go同上复用 v2 协议的 model-ready 语义gRPC 客户端、CI 脚本控制平面 / K8sseldon pipeline status的modelsReady、kubectl wait --for conditionready与status.conditions[0]ModelsReadypipeline_types.go调度器状态 / Operator CRD condition部署编排、K8s 准入控制关键要点Pipeline 存在 ≠ Pipeline 就绪。加载 Pipeline 后必须等全部 step 模型加载完成modelsReady: true数据平面才返回{ready: true}gRPC 查 Pipeline 就绪必须带seldon-model:name.pipeline请求头否则 Gateway 无法区分这是对 Pipeline 还是对单个 Model 的查询模型状态独立于 Pipeline 生命周期。卸载 Pipeline 后模型仍保持 ready重新 load 可秒级恢复模型 unload 后modelsReady回落为nullK8s 环境优先用 kubectl 操作 CRDkubectl wait --for conditionready配合ModelsReadycondition 排查非 K8s 环境可用seldonCLI 完成同样的 load/status/unload 流程。赞分享人工智能大模型MLOpsLLMOps模型推理服务云原生后端【免费下载链接】seldon-coreAn MLOps framework to package, deploy, monitor and manage thousands of production machine learning models项目地址https://gitcode.com/gh_mirrors/se/seldon-core点击查看免费下载相关推荐Seldon Core v2 seldon pipeline status 命令详解查询与等待 Pipeline 运行状态Seldon Core v2 seldon pipeline status 命令详解查询与等待 Pipeline 运行状态 本篇技术指南围绕 Seldon C人工智能大模型MLOpsLLMOps模型推理服务云原生后端CoreDNS ready 插件深入指南基于 /ready 端点的插件就绪状态探测与实战配置CoreDNS ready 插件深入指南基于 /ready 端点的插件就绪状态探测与实战配置 ready 是 CoreDNS 内置的就绪检查readines后端网络云原生Seldon Core 2 CLI 实战使用 seldon experiment status 查询与等待实验Experiment状态Seldon Core 2 CLI 实战使用 seldon experiment status 查询与等待实验Experiment状态 本文聚焦 Seld人工智能大模型MLOpsLLMOps模型推理服务云原生后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考