人工智能模型的训练与推理正从单机实验走向生产级部署,而云原生技术(容器、编排、服务网格、可观测性)为这一转变提供了标准化的基础设施底座。AI + 云原生 的核心价值在于:通过Kubernetes的声明式API管理GPU资源,利用自动伸缩(HPA/VPA)应对推理流量的潮汐波动,借助服务网格实现灰度发布与流量镜像,最终将AI生命周期(数据准备、训练、调优、部署、监控)无缝融入DevOps流水线。
本文将以KServe(云原生模型服务框架)和Kubeflow为核心,演示如何在Kubernetes集群中部署一个支持弹性伸缩与金丝雀发布的AI推理服务,并辅以Prometheus监控与自定义指标HPA,构建生产级的MLOps闭环。
首先,集群需识别GPU资源(NVIDIA A100/V100)。通过安装NVIDIA Device Plugin,Kubernetes可感知节点上的GPU数量:
# 部署NVIDIA设备插件
kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.0/nvidia-device-plugin.yaml
# 验证GPU资源
kubectl describe node gpu-node | grep nvidia.com/gpu为训练作业预留GPU时,在Pod的resources中声明:
resources:
limits:
nvidia.com/gpu: 1 # 占用整卡
requests:
nvidia.com/gpu: 1对于推理服务,可采用GPU共享技术(如vGPU或MIG)提升利用率。
Kubeflow Pipelines允许将训练代码容器化,并编排成可重用的工作流。以下是一个使用Python SDK定义的训练组件(基于PyTorch):
# train_component.py
from kfp import dsl
from kfp.components import create_component_from_func
@create_component_from_func
def train_model(data_path: str, epochs: int, output_model: str) -> str:
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
# 模拟简单MLP训练(实际可替换为ResNet/Transformer)
X = torch.randn(10000, 128)
y = torch.randint(0, 10, (10000,))
model = nn.Sequential(nn.Linear(128, 256), nn.ReLU(), nn.Linear(256, 10))
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
loader = DataLoader(TensorDataset(X, y), batch_size=64, shuffle=True)
for epoch in range(epochs):
for batch_x, batch_y in loader:
optimizer.zero_grad()
loss = nn.CrossEntropyLoss()(model(batch_x), batch_y)
loss.backward()
optimizer.step()
torch.save(model.state_dict(), f"{output_model}/model.pth")
return f"{output_model}/model.pth"
# 流水线定义
@dsl.pipeline(name='training-pipeline')
def pipeline(data_path: str = '/data', epochs: int = 5):
train_task = train_model(data_path=data_path, epochs=epochs, output_model='/mnt/models')
# 后续可接模型评估、推送至模型注册表等编译并提交至Kubeflow集群:
dsl-compile --py train_component.py --output pipeline.yaml
kubectl apply -f pipeline.yaml训练产出的模型需以高可用方式暴露为在线服务。KServe(原KFServing)提供了Serverless推理能力,支持TensorFlow、PyTorch、ONNX等运行时,并内置金丝雀发布、自动伸缩和请求级批处理。
1. 定义InferenceService资源
将模型存储至S3兼容对象存储(如MinIO),并创建Service YAML:
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
name: iris-classifier
spec:
predictor:
minReplicas: 1
maxReplicas: 10
scaleMetric: concurrency # 基于并发数伸缩
scaleTarget: 10 # 每个Pod目标并发数
containers:
- name: kserve-container
image: kserve/pytorchserver:latest
resources:
limits:
cpu: "2"
memory: "4Gi"
nvidia.com/gpu: 1
env:
- name: MODEL_NAME
value: iris-model
- name: STORAGE_URI
value: s3://my-bucket/iris/model.pth # 模型路径
# 金丝雀配置:将10%流量导向新版本
canaryTrafficPercent: 102. 客户端请求示例
部署后,服务通过Istio Ingress暴露,发送JSON请求进行推理:
import requests
import json
# 获取Ingress地址
service_url = "http://kserve-ingress.<namespace>.example.com/v1/models/iris-classifier:predict"
payload = {
"instances": [[5.1, 3.5, 1.4, 0.2], [6.7, 3.1, 4.7, 1.5]] # 鸢尾花特征
}
headers = {"Host": "iris-classifier.default.example.com", "Content-Type": "application/json"}
response = requests.post(service_url, json=payload, headers=headers)
print(response.json()) # 输出类别预测默认的CPU/内存HPA无法准确反映推理负载。KServe会暴露request_count、request_latency等Prometheus指标,我们可自定义HPA基于每秒请求数(RPS) 伸缩。
部署Prometheus Adapter,配置指标规则:
# prometheus-adapter-config.yaml
rules:
- seriesQuery: 'kserve_requests_total{namespace!="",service_name!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
service_name: {resource: "service"}
name:
as: "rps_per_pod"
metricsQuery: 'sum(rate(kserve_requests_total{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>)'然后创建HPA指向KServe的Deployment(实际为KServe的ScaleTarget):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: iris-classifier-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: iris-classifier-predictor-default
minReplicas: 2
maxReplicas: 20
metrics:
- type: Pods
pods:
metric:
name: rps_per_pod
target:
type: AverageValue
averageValue: "50" # 每个Pod承载50 RPS当流量突增时,HPA自动扩容Pod,流量下降后缩容,显著节省GPU成本。
云原生可观测性三板斧:日志(EFK/ELK)、指标(Prometheus/Grafana)、链路追踪(Jaeger)。为推理服务注入Trace,可定位慢请求原因:
# 在推理代码中添加OpenTelemetry
from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("predict") as span:
span.set_attribute("model_name", "iris-classifier")
result = model.predict(instances)
span.set_attribute("prediction_count", len(result))同时,借助Istio的流量镜像,将生产流量复制到新模型版本,验证正确性后再逐步提升金丝雀流量比例,实现零风险上线。
AI + 云原生并非简单地将训练脚本跑在容器中,而是构建从数据到模型的自动化流水线,并赋予推理服务弹性、高可用、可观测、灰度发布等云原生基因。本文以Kubeflow Pipelines定义训练流,以KServe部署弹性推理服务,结合自定义指标HPA和Prometheus监控,展示了完整的MLOps实践。未来,随着Serverless容器(如Knative)和GPU池化技术的成熟,AI基础设施将更加精细化和成本优化。建议读者在本地Kind或云厂商Kubernetes环境中动手实践,用真实模型(如BERT或ResNet)验证上述架构,并逐步引入模型版本管理和A/B实验,最终打造适应业务突发的智能应用基石。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。