
1、AI程序员系列文章2、AI面试系列文章3、AI编程系列文章 本文是《AI云原生实战调研》系列第九篇。上一篇我们拆解了零售业200标签用户画像与KEDA弹性架构这一篇我们回归核心技术栈——把模型从训练的GPU集群一路送到线上推理引擎中间全程自动化再也不用人工copy模型文件了。目录一、训推一体架构核心思想模型的全生命周期到底长什么样二、Kubeflow的角色不止是训练是整个ML工厂2.1 Kubeflow到底是什么2.2 Kubeflow Pipeline的核心概念2.3 Katib超参优化别再手动调参了三、Seldon Core的角色推理引擎的正确打开方式3.1 Seldon Core到底解决什么问题3.2 SeldonDeployment CRD核心字段3.3 Seldon Core支持的内置推理服务器四、协同部署完整流程从零搭建训推一体平台4.1 步骤1安装Kubeflow4.2 步骤2部署Seldon Core4.3 步骤3部署MLflow模型注册中心4.4 步骤4定义SeldonDeployment K8s Service/Ingress五、Pipeline设计数据预处理→训练→评估→注册→部署六、模型版本管理MLflow Seldon Canary部署6.1 MLflow Model Registry6.2 Seldon Canary部署新旧版本梯度切换七、A/B测试Seldon流量分割实战7.1 什么是ML场景的A/B测试7.2 多模型A/B测试配置八、完整落地清单开篇那个凌晨三点还在手动scp模型文件的倒霉蛋2024年6月某AI创业公司的算法工程师小陈凌晨2:47。他干了件几乎所有搞AI的人都干过的事——手动部署模型。流程是这样的训练脚本跑完了 → 从GPU服务器上scp模型文件到本地 → 再scp到生产服务器 → 重启推理服务 → 盯着日志看有没有报错 → 发现依赖版本不对 → 重新装依赖 → 再重启 → 终于跑起来了 → 一看表凌晨3:42。更离谱的是第二天早上产品经理在群里他“昨晚上的模型是不是有问题用户的推理请求有一半返回了空结果。”排查了两个小时发现是scp的时候断了一次网模型文件传了一半。剩下的一半是零字节填充的——推理引擎加载了一个损坏的模型权重对着一半的请求输出垃圾结果。残酷真相手动部署模型这件事就像用手摇窗户一样——在2024年还这么干的团队不是在开发AI产品是在用体力换安全感。今天这篇我们聊一个能让算法工程师睡个好觉的方案——Kubeflow Seldon Core 训推一体架构。从训练Pipeline到模型注册到生产部署到A/B测试全链路自动化。完整YAML配置都在下面不藏私。一、训推一体架构核心思想模型的全生命周期到底长什么样先说一个认知模型的问题。很多人理解的AI部署长这样训练完模型 → 保存pth文件 → 找运维装环境 → 启个Flask服务 → 结束但真实的生产级AI模型生命周期其实长这样graph LR A[ 数据预处理br/清洗/特征工程/切分] -- B[️ 模型训练br/分布式训练/超参调优] B -- C[ 模型评估br/AUC/准确率/PSI稳定性] C -- D[ 模型注册br/MLflow Registrybr/版本管理] D -- E[ 模型部署br/Seldon Corebr/自动滚动更新] E -- F[ A/B测试br/流量分割br/指标对比] F -- G[ 生产监控br/延迟/错误率/数据漂移] G --|触发重训练| A style A fill:#e3f2fd,stroke:#1565c0 style B fill:#e8f5e9,stroke:#2e7d32 style C fill:#fff3e0,stroke:#e65100 style D fill:#f3e5f5,stroke:#6a1b9a style E fill:#fce4ec,stroke:#c62828 style F fill:#e0f2f1,stroke:#00695c style G fill:#fff8e1,stroke:#f9a825这不是线性流程这是一个闭环。模型上线不是终点是新一轮迭代的起点。训推一体架构的核心思想就一句话把训练Training和推理Inference放在同一个平台、同一套流程里管理让模型的训练、评估、注册、部署、监控形成一个自动化闭环。在K8s生态里这个闭环由两个核心组件分工完成组件角色核心能力Kubeflow训练工厂Pipeline编排 Katib超参优化 Notebook开发环境Seldon Core推理引擎模型服务化 多模型路由 A/B测试 金丝雀部署它们的关系可以类比成Kubeflow是工厂生产模型Seldon Core是商店卖模型服务。工厂生产好了商品自动推到商店货架上——中间不需要任何人手动搬箱子。二、Kubeflow的角色不止是训练是整个ML工厂2.1 Kubeflow到底是什么很多人对Kubeflow有误解以为它就是个K8s上跑TensorFlow的东西。其实Kubeflow是一个端到端的ML工作流平台它提供的核心能力包括Kubeflow Pipelines用DAG有向无环图定义ML工作流每个步骤跑在一个独立容器里Katib自动化超参数调优支持贝叶斯优化、TPE、网格搜索等算法Notebooks内置Jupyter Notebook可申请GPU资源直接开发Training Operators支持TFJob、PyTorchJob、MPIJob等分布式训练CRDKServe原KFServing无服务器模型推理引擎与Seldon Core互补认知纠偏Kubeflow本身不是训练框架它不管你用PyTorch还是TensorFlow。它就像一个自动化工厂流水线——你只需要定义什么时候做什么事剩下的事情它帮你调度、追踪、重试。2.2 Kubeflow Pipeline的核心概念一个典型的Kubeflow Pipeline由多个Component通过数据依赖关系串联而成。每个Component本质上是一个被容器化的Python函数。# Kubeflow Pipeline组件定义示例 # 数据预处理组件 apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: ml-training-pipeline- spec: entrypoint: ml-pipeline templates: - name: ml-pipeline dag: tasks: # 步骤1数据预处理 - name:>2.3 Katib超参优化别再手动调参了Katib是Kubeflow内置的AutoML组件。你定义要调哪些参数、优化目标是什么、用什么算法Katib自动跑N组实验找到最优参数组合。# Katib Experiment 配置 apiVersion: kubeflow.org/v1beta1 kind: Experiment metadata: name: random-forest-hpo namespace: kubeflow spec: objective: type: maximize goal: 0.95 # 目标AUC ≥ 0.95 objectiveMetricName: auc additionalMetricNames: - accuracy - f1_score algorithm: algorithmName: bayesianoptimization # 贝叶斯优化 # 比网格搜索效率高5-10倍 parallelTrialCount: 3 # 并行跑3组实验 maxTrialCount: 30 # 最多跑30组 maxFailedTrialCount: 5 # 允许失败5次 parameters: - name: n_estimators parameterType: int feasibleSpace: min: 100 max: 1000 - name: max_depth parameterType: int feasibleSpace: min: 3 max: 20 - name: learning_rate parameterType: double feasibleSpace: min: 0.001 max: 0.3 trialTemplate: primaryContainerName: training-container trialParameters: - name: nEstimators reference: n_estimators - name: maxDepth reference: max_depth - name: lr reference: learning_rate trialSpec: apiVersion: batch/v1 kind: Job spec: template: spec: containers: - name: training-container image: my-registry/train-rf:latest command: - python - train.py - --n-estimators${trialParameters.nEstimators} - --max-depth${trialParameters.maxDepth} - --lr${trialParameters.lr} resources: limits: nvidia.com/gpu: 1 restartPolicy: NeverKatib使用技巧parallelTrialCount建议设置为GPU数量的一半。因为每个Trial独占一张GPU的话设置成全部GPU数会让集群瞬间打满其他服务受影响。另外maxFailedTrialCount一定要设——如果搜索空间里有一些明显离谱的组合比如depth3、lr0.001实验会一直跑不出结果没设这个参数的话工作流会卡到天荒地老。三、Seldon Core的角色推理引擎的正确打开方式3.1 Seldon Core到底解决什么问题如果Kubeflow是工厂那Seldon Core就是商店——它负责把模型卖服务出去。传统的模型推理部署方式是搞个Flask/FastAPI → 加载模型 → 写个/predict端点 → 手动起docker → 手动配Nginx → 手动管理多模型版本 → 手动切流量。Seldon Core把这个流程变成了声明式K8s CRD——你写一个SeldonDeployment YAML它自动帮你搞定Container创建、Service暴露、负载均衡、流量分割、A/B测试、日志监控。全程不用写一行Flask代码。3.2 SeldonDeployment CRD核心字段# 最简SeldonDeployment示例 apiVersion: machinelearning.seldon.io/v1 kind: SeldonDeployment metadata: name: iris-classifier namespace: seldon spec: name: iris-model predictors: - name: default graph: name: classifier implementation: SKLEARN_SERVER # 内置推理服务器 modelUri: s3://models/iris/v1 # 模型文件路径 envSecretRefName: seldon-init-container-secret # S3/MinIO凭证 replicas: 2 # 资源限制推理服务通常显存放宽、CPU可控 componentSpecs: - spec: containers: - name: classifier resources: requests: cpu: 1 memory: 2Gi nvidia.com/gpu: 1 limits: cpu: 2 memory: 4Gi nvidia.com/gpu: 1注意modelUri可以指向S3、GCS、MinIO、PVC等任何Seldon支持的存储后端。Seldon的Init Container会在Pod启动前自动拉取模型文件。3.3 Seldon Core支持的内置推理服务器你不需要自己写推理服务的HTTP/gRPC封装Seldon内置了以下预打包服务器预打包服务器适用框架说明SKLEARN_SERVERScikit-learnjoblib加载REST/gRPC双协议MLFLOW_SERVERMLflow模型自动加载MLflow格式模型TENSORFLOW_SERVERTensorFlowSavedModel格式XGBOOST_SERVERXGBoost支持多模型版本TEMPO_SERVER自定义Python写Python类即可无需框架⚠️框架选择陷阱如果你的模型是用PyTorch训练的别直接用预打包服务器它们都不原生支持PyTorch。需要自定义Docker镜像或者用Triton Inference Server替代。Seldon也支持挂自定义镜像——implementation: CUSTOMcontainerImage: your-registry/torch-model:v1。四、协同部署完整流程从零搭建训推一体平台好现在进入重头戏——怎么把Kubeflow和Seldon Core串起来搞成一个能跑通的训推一体流水线。整个流程分为四个阶段graph TB subgraph Phase1[ 阶段1环境准备] A1[安装Kubeflowbr/kfctl/manifests] A2[部署Seldon Corebr/Helm安装] A3[部署MLflowbr/模型注册中心] A1 -- A2 -- A3 end subgraph Phase2[️ 阶段2Pipeline开发] B1[定义数据预处理br/Component] B2[定义训练评估br/Component] B3[定义注册部署br/Component] B1 -- B2 -- B3 end subgraph Phase3[ 阶段3自动部署] C1[Pipeline触发br/训练完成] C2[生成SeldonDeploymentbr/YAML] C3[kubectl applybr/自动滚动更新] C1 -- C2 -- C3 end subgraph Phase4[ 阶段4验证迭代] D1[A/B测试br/流量分割] D2[Prometheusbr/指标对比] D3[触发重训练br/Katib调参] D1 -- D2 -- D3 end Phase1 -- Phase2 -- Phase3 -- Phase4 style Phase1 fill:#e3f2fd,stroke:#1565c0 style Phase2 fill:#e8f5e9,stroke:#2e7d32 style Phase3 fill:#fff3e0,stroke:#e65100 style Phase4 fill:#fce4ec,stroke:#c628284.1 步骤1安装Kubeflow# 方式一使用kfctl推荐省心 wget https://github.com/kubeflow/kfctl/releases/download/v1.9.0/kfctl_v1.9.0_linux_amd64.tar.gz tar -xzf kfctl_v1.9.0_linux_amd64.tar.gz export PATH$PATH:$(pwd) # 设置环境变量 export KF_NAMEkubeflow-cluster export BASE_DIR/opt/kubeflow export KF_DIR${BASE_DIR}/${KF_NAME} export CONFIG_URLhttps://raw.githubusercontent.com/kubeflow/manifests/v1.9-branch/kfdef/kfctl_istio_dex.v1.9.0.yaml mkdir -p ${KF_DIR} cd ${KF_DIR} kfctl apply -V -f ${CONFIG_URL} # 验证安装这个命令会等几分钟 kubectl get pods -n kubeflow -w⚠️Kubeflow安装血泪史Kubeflow是一个重依赖的平台安装时会拉取Istio、Knative、Cert-Manager、Dex等一堆组件。整个安装过程需要20-40分钟中间可能有Pod重启、ImagePullBackOff等情况。不要慌看日志排查就行。另外——Kubeflow最低要求K8s集群16核CPU 32GB内存用minikube/minikube本地测试环境大概率跑不起来。4.2 步骤2部署Seldon Core# 添加Helm仓库 helm repo add seldon https://storage.googleapis.com/seldon-charts helm repo update # 创建命名空间 kubectl create namespace seldon-system # 安装Seldon Core Operator带Istio集成 helm install seldon-core seldon/seldon-core-operator \ --namespace seldon-system \ --set istio.enabledtrue \ --set istio.gatewayistio-system/seldon-gateway \ --set executor.requestLogger.defaultEndpointhttp://default-broker.knative-eventing \ --set usageMetrics.enabledtrue # 验证 kubectl get pods -n seldon-system # 期望输出seldon-controller-manager-xxx 1/1 Running4.3 步骤3部署MLflow模型注册中心# MLflow Tracking Server部署 kubectl create namespace mlflow # 使用PostgreSQL作为后端存储 cat EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: mlflow-server namespace: mlflow spec: replicas: 1 selector: matchLabels: app: mlflow template: metadata: labels: app: mlflow spec: containers: - name: mlflow image: ghcr.io/mlflow/mlflow:v2.14.0 command: - mlflow - server - --backend-store-uri - postgresql://user:passpostgres-svc:5432/mlflow - --default-artifact-root - s3://mlflow-artifacts/ - --host - 0.0.0.0 - --port - 5000 ports: - containerPort: 5000 env: - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: name: s3-credentials key: access-key - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: name: s3-credentials key: secret-key --- apiVersion: v1 kind: Service metadata: name: mlflow-svc namespace: mlflow spec: selector: app: mlflow ports: - port: 5000 targetPort: 5000 EOFMLflow部署建议生产环境一定要用数据库MySQL/PostgreSQL作为backend store不要用默认的本地文件系统。否则模型一多metadata查询慢到崩溃。artifact存储推荐用S3或MinIO——模型文件动辄几百MB到几GB本地PVC扛不住多副本共享。4.4 步骤4定义SeldonDeployment K8s Service/Ingress当Pipeline训练完成、模型注册到MLflow后最后一步是自动生成并apply SeldonDeployment YAML# 自动生成的 SeldonDeployment完整版 apiVersion: machinelearning.seldon.io/v1 kind: SeldonDeployment metadata: name: fraud-detection-v1 namespace: ml-models labels: model: fraud-detection version: v1.0.0 spec: name: fraud-detection predictors: - name: v1-predictor graph: name: fraud-classifier implementation: MLFLOW_SERVER modelUri: s3://mlflow/1/abc123def456/artifacts/model # MLflow自动生成的artifact路径 envSecretRefName: seldon-init-container-secret # ⚠️ 模型预热配置Pod启动后、加入Service Endpoints前先跑几轮推理热机 logger: mode: all replicas: 3 # 推理引擎资源GPU留给模型推理CPU留给预处理 componentSpecs: - spec: containers: - name: fraud-classifier image: seldonio/mlflowserver:1.19.0 resources: requests: cpu: 2 memory: 4Gi nvidia.com/gpu: 1 limits: cpu: 4 memory: 8Gi nvidia.com/gpu: 1 # 健康检查重点检查模型是否加载成功 livenessProbe: httpGet: path: /v2/models/fraud-classifier/ready port: 9000 initialDelaySeconds: 60 # 模型加载需要时间 periodSeconds: 15 failureThreshold: 5 readinessProbe: httpGet: path: /v2/models/fraud-classifier/ready port: 9000 initialDelaySeconds: 30 periodSeconds: 10 failureThreshold: 3 --- # K8s Service apiVersion: v1 kind: Service metadata: name: fraud-detection-svc namespace: ml-models spec: selector: app: seldon predictor: v1-predictor ports: - port: 8000 targetPort: 8000 name: http - port: 9000 targetPort: 9000 name: grpc --- # Ingress对外暴露推理API apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: fraud-detection-ingress namespace: ml-models annotations: nginx.ingress.kubernetes.io/proxy-body-size: 10m nginx.ingress.kubernetes.io/proxy-read-timeout: 60 nginx.ingress.kubernetes.io/proxy-send-timeout: 60 cert-manager.io/cluster-issuer: letsencrypt-prod spec: ingressClassName: nginx tls: - hosts: - ml-api.yourdomain.com secretName: ml-api-tls rules: - host: ml-api.yourdomain.com http: paths: - path: /api/v1/predict pathType: Prefix backend: service: name: fraud-detection-svc port: number: 8000⚠️livenessProbe超时大坑GPU模型加载通常需要10-60秒取决于模型大小。如果你的initialDelaySeconds设成15秒Pod会在模型还没加载完的时候就被kubelet杀掉重启然后进入无限重启循环。initialDelaySeconds至少设为模型加载时间的2倍。如果不确定模型加载多久先用kubectl run一个临时Pod测一下。五、Pipeline设计数据预处理→训练→评估→注册→部署现在我们把整个Pipeline串起来用Python SDK定义完整工作流# kubeflow_pipeline.py — 完整训推一体Pipeline import kfp from kfp import dsl from kfp.dsl import Input, Output, Dataset, Model, Metrics from kubernetes import client as k8s_client # 组件1数据预处理 dsl.component( base_imagepython:3.10-slim, packages_to_install[pandas, scikit-learn, boto3] ) def preprocess_data( raw_data_path: str, output_data: Output[Dataset] ): import pandas as pd from sklearn.model_selection import train_test_split # 从S3/MinIO读取原始数据 df pd.read_parquet(raw_data_path) # 数据清洗 特征工程 df df.dropna(subset[amount, merchant_id]) df[hour] pd.to_datetime(df[timestamp]).dt.hour df[amount_log] df[amount].apply(lambda x: __import__(math).log1p(x)) # 划分训练集/测试集 train, test train_test_split(df, test_size0.2, stratifydf[label]) train.to_parquet(output_data.path /train.parquet) test.to_parquet(output_data.path /test.parquet) print(f训练集: {len(train)} 条, 测试集: {len(test)} 条) # 组件2模型训练 dsl.component( base_imagepython:3.10-slim, packages_to_install[xgboost, pandas, scikit-learn, mlflow, boto3] ) def train_model( train_data: Input[Dataset], model_output: Output[Model], n_estimators: int 200, max_depth: int 6, learning_rate: float 0.1 ): import pandas as pd import xgboost as xgb import mlflow from sklearn.metrics import roc_auc_score, accuracy_score # 开启MLflow追踪 mlflow.set_tracking_uri(http://mlflow-svc.mlflow:5000) mlflow.set_experiment(fraud-detection) # 加载预处理数据 train pd.read_parquet(train_data.path /train.parquet) test pd.read_parquet(train_data.path /test.parquet) X_train, y_train train.drop(label, axis1), train[label] X_test, y_test test.drop(label, axis1), test[label] with mlflow.start_run(): # 训练XGBoost model xgb.XGBClassifier( n_estimatorsn_estimators, max_depthmax_depth, learning_ratelearning_rate, eval_metricauc, use_label_encoderFalse ) model.fit(X_train, y_train, eval_set[(X_test, y_test)], verboseFalse) # 评估 y_pred model.predict(X_test) auc roc_auc_score(y_test, y_pred) acc accuracy_score(y_test, y_pred) # 记录指标到MLflow mlflow.log_params({ n_estimators: n_estimators, max_depth: max_depth, learning_rate: learning_rate }) mlflow.log_metrics({auc: auc, accuracy: acc}) # 保存模型到MLflow mlflow.xgboost.log_model(model, model) run_id mlflow.active_run().info.run_id print(f训练完成! AUC: {auc:.4f}, Accuracy: {acc:.4f}) print(fMLflow Run ID: {run_id}) # 组件3模型评估 dsl.component( base_imagepython:3.10-slim, packages_to_install[pandas, scikit-learn, mlflow, boto3] ) def evaluate_model( mlflow_run_id: str, eval_metrics: Output[Metrics] ): import mlflow mlflow.set_tracking_uri(http://mlflow-svc.mlflow:5000) # 从MLflow拉取训练指标 client mlflow.tracking.MlflowClient() run client.get_run(mlflow_run_id) auc run.data.metrics[auc] accuracy run.data.metrics[accuracy] metrics {auc: auc, accuracy: accuracy} eval_metrics.log_metric(auc, auc) eval_metrics.log_metric(accuracy, accuracy) # 质量门禁 if auc 0.85 or accuracy 0.80: raise ValueError(f⚠️ 模型质量不达标! AUC{auc:.4f}, Accuracy{accuracy:.4f}) print(f✅ 模型通过质量门禁! AUC{auc:.4f}, Accuracy{accuracy:.4f}) # 组件4自动部署 dsl.component( base_imagepython:3.10-slim, packages_to_install[kubernetes, pyyaml] ) def deploy_to_seldon( mlflow_run_id: str, model_name: str fraud-detection, model_version: str v1 ): from kubernetes import client, config import yaml # ⚠️ 这里需要集群内认证 config.load_incluster_config() # 构造SeldonDeployment YAML seldon_deploy { apiVersion: machinelearning.seldon.io/v1, kind: SeldonDeployment, metadata: { name: f{model_name}-{model_version}, namespace: ml-models, labels: {model: model_name, version: model_version} }, spec: { name: model_name, predictors: [{ name: f{model_version}-predictor, graph: { name: classifier, implementation: MLFLOW_SERVER, modelUri: fs3://mlflow/artifacts/{mlflow_run_id}/model, envSecretRefName: seldon-init-container-secret }, replicas: 2, componentSpecs: [{ spec: { containers: [{ name: classifier, resources: { requests: {cpu: 1, memory: 2Gi}, limits: {cpu: 2, memory: 4Gi} } }] } }] }] } } # Apply到K8s集群 api client.CustomObjectsApi() api.create_namespaced_custom_object( groupmachinelearning.seldon.io, versionv1, namespaceml-models, pluralseldondeployments, bodyseldon_deploy ) print(f 模型 {model_name}/{model_version} 已部署到Seldon Core!) # 组装Pipeline dsl.pipeline( nameFraud Detection Training Pipeline, description训推一体Pipeline数据预处理→训练→评估→部署 ) def fraud_detection_pipeline( raw_data_path: str s3://datasets/fraud/raw/, n_estimators: int 200, max_depth: int 6, learning_rate: float 0.1 ): # 步骤1数据预处理 preprocess_task preprocess_data(raw_data_pathraw_data_path) # 步骤2训练 train_task train_model( train_datapreprocess_task.outputs[output_data], n_estimatorsn_estimators, max_depthmax_depth, learning_ratelearning_rate ) # 步骤3评估 eval_task evaluate_model(mlflow_run_idtrain_task.output) # 步骤4自动部署到Seldon Core deploy_task deploy_to_seldon(mlflow_run_idtrain_task.output) deploy_task.after(eval_task) # 评估通过后才部署 # 编译并上传Pipeline if __name__ __main__: kfp.compiler.Compiler().compile( fraud_detection_pipeline, fraud_detection_pipeline.yaml )Pipeline设计黄金法则每个Component应该只做一件事。不要在一个Component里既预处理数据又训练模型——拆开的好处是预处理挂了你不需要重跑训练训练挂了不需要重跑预处理。而且拆开后每个Component可以在Pipeline UI里独立重跑。六、模型版本管理MLflow Seldon Canary部署6.1 MLflow Model Registry模型训练好后不能直接上线。要走Staging → Production → Archived的标准流程。# MLflow模型版本管理 import mlflow from mlflow.tracking import MlflowClient client MlflowClient() # 注册模型到Registry model_uri fruns:/{run_id}/model registered_model mlflow.register_model(model_uri, FraudDetectionModel) # 添加描述和标签 client.update_model_version( nameFraudDetectionModel, versionregistered_model.version, descriptionXGBoost fraud detection v2, 训练数据: 2024Q2 ) # ⚠️ 关键步骤先走Staging验证通过再升Production client.transition_model_version_stage( nameFraudDetectionModel, versionregistered_model.version, stageStaging, archive_existing_versionsFalse ) print(f模型已注册: FraudDetectionModel v{registered_model.version} → Staging)6.2 Seldon Canary部署新旧版本梯度切换transition_stage到Production后不能直接100%切流量。用Seldon的Canary策略# Canary部署v1稳定版 v2金丝雀版 apiVersion: machinelearning.seldon.io/v1 kind: SeldonDeployment metadata: name: fraud-detection-canary namespace: ml-models spec: name: fraud-detection predictors: # v1稳定版主力 - name: v1-stable traffic: 95 # 95%流量 graph: name: fraud-classifier implementation: MLFLOW_SERVER modelUri: s3://mlflow/artifacts/stable/model replicas: 3 # v2金丝雀版新模型 - name: v2-canary traffic: 5 # 5%流量 → 观察后逐步提升 graph: name: fraud-classifier-v2 implementation: MLFLOW_SERVER modelUri: s3://mlflow/artifacts/latest/model replicas: 1 # 金丝雀版本只需1个副本⚠️Canary阶段观察清单观察阶段v2流量持续时间关键指标回滚条件初始观察5%4小时错误率、响应延迟P99错误率 5%中等放量20%24小时吞吐量、内存OOMP99延迟 1.5倍基线大流量验证50%24小时业务指标AUC、通过率AUC下降 3%全量切换100%-v1保留7天后下线-七、A/B测试Seldon流量分割实战7.1 什么是ML场景的A/B测试A/B测试在ML场景和传统Web场景不一样。传统A/B测试比的是UI布局、按钮颜色ML的A/B测试比的是模型效果——同一个输入模型A和模型B给出的预测是否有显著差异Seldon Core的流量分割可以基于多种策略固定权重分流v1 50% v2 50%Header路由特定用户打到特定模型x-model-version: v2影子流量用户请求同时打给v1和v2但只返回v1结果shadow deployment7.2 多模型A/B测试配置# A/B测试三模型并行对比 apiVersion: machinelearning.seldon.io/v1 kind: SeldonDeployment metadata: name: fraud-ab-test namespace: ml-models spec: name: fraud-detection predictors: # 模型A当前主力 XGBoost - name: xgboost-baseline traffic: 60 graph: name: xgb-classifier implementation: MLFLOW_SERVER modelUri: s3://mlflow/artifacts/xgboost/prod/model replicas: 3 # 模型B新版 XGBoostKatib调参后 - name: xgboost-optimized traffic: 30 graph: name: xgb-optimized implementation: MLFLOW_SERVER modelUri: s3://mlflow/artifacts/xgboost/v2/model replicas: 2 # 模型C实验性 LightGBM - name: lightgbm-experimental traffic: 10 graph: name: lgb-experiment implementation: MLFLOW_SERVER modelUri: s3://mlflow/artifacts/lgb/experimental/model replicas: 1 --- # A/B测试结果对比API自定义指标采集 apiVersion: v1 kind: ConfigMap metadata: name: ab-test-metrics namespace: ml-models data: metrics.py: | from prometheus_client import Gauge, Histogram # 按模型版本区分指标 model_auc Gauge( model_auc_score, 模型AUC分数, [model_version, model_type] ) model_latency Histogram( model_inference_latency_seconds, 模型推理延迟, [model_version], buckets[0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5] ) model_error_rate Gauge( model_error_rate, 模型错误率, [model_version] )流量分割最佳实践A/B测试期间一定要保证同一个用户的所有请求打到同一个模型版本否则用户体验会崩第一次预测高风险拒绝交易第二次预测低风险放行用户直接懵了。可以用Header里的session-id做一致性哈希路由# Seldon A/B测试 会话亲和性 annotations: seldon.io/engine-seldon-container-routing.map: | {session-id: {{request.headers.x-session-id}}}八、完整落地清单把前面七章串起来训推一体架构在K8s上的完整落地清单序号环节核心组件关键配置优先级1环境搭建K8s集群 ≥16核32G安装Kubeflow Seldon MLflow P02Pipeline开发Kubeflow PipelinesComponent拆分、PVC数据传递 P03超参优化Katib贝叶斯优化、并行Trial、早停 P14模型训练TFJob/PyTorchJobGPU资源请求、分布式策略 P05模型评估Pipeline组件质量门禁AUC0.85等 P06模型注册MLflow RegistryStaging→Production流程 P07模型部署SeldonDeployment CRDmodelUri、资源限制、健康检查 P08服务暴露Service IngressTLS、限流、probe超时 P19A/B测试Seldon流量分割Canary权重、会话亲和性 P110生产监控Prometheus GrafanaAUC漂移、P99延迟、错误率 P0九、写在最后自动化不是偷懒是不给自己犯错的机会很多人觉得搞Pipeline、CRD、自动部署这些东西是在把简单问题复杂化——“我就训个模型直接scp过去不行吗”行当然行。但当你同时管理5个模型版本、每个版本对应3个部署环境、每天有2次模型更新、还有4个实验性模型在跑A/B测试的时候——手动管理不是挑战是灾难。Kubeflow和Seldon Core这套组合拳的本质不是让你少写几行代码而是消除人工操作带来的不确定性你不会再传一半断网的模型文件你不会再忘记改依赖版本你不会再漏掉某个环境的部署你不会再不知道哪个模型版本跑在线上自动化不是偷懒。自动化是职业素养——承认自己会犯错然后用系统而不是意志力来保证不出错。下篇预告KEDA事件驱动扩缩容——让AI服务按需伸缩。一条Kafka消息、一次HTTP请求、一组Prometheus指标都能触发你的AI服务从0个Pod自动扩到N个。ScaledObject ScaledJob 20多种Scaler30秒内完成扩容响应——下一篇我们聊聊如何让推理服务真正实现零闲置、不丢请求的弹性体验。️ 标签#Kubeflow #Seldon Core #训推一体 #MLflow #A/B测试 #Kubernetes #MLOps 本文为《AI云原生实战调研》系列第九篇。 往期回顾[01-AI云原生全景为什么75%的企业都在用混合云部署AI][02-Docker容器化AI模型从PyTorch到TensorFlow的最佳实践][03-Kubernetes管理AI工作负载Job/Deployment/StatefulSet怎么选][04-GPU资源调度深度实战NVIDIA MIG与Time Slicing与HAMi][05-金融行业AI云原生实战腾讯云TCE银行智能风控平台][06-医疗行业AI云原生实战阿里云ACK安全沙箱与隐私保护][07-制造业AI云原生实战湘钢5G云AI生产安全监控][08-零售业AI云原生实战奇点数聚全渠道用户画像] 本文场景训推一体平台 · Kubeflow Pipeline · Seldon Core服务化 交流你们的团队模型发布流程是手动还是自动化的Pipeline跑一次要多久欢迎评论区分享你的真实体验——踩过的坑、省下的时间、被老板夸过的瞬间。⭐ 关注点赞收藏不迷路下一篇KEDA事件驱动弹性扩缩容让你的AI服务真正按需伸缩、零闲置我们不见不散。