6.14 MLOps 入门——模型训练基础设施与 GPU 集群调度
预计阅读时间:17 分钟
📖 目录
模型从实验到上线,涉及数据准备、训练、评估、部署、监控等多个环节。MLOps 将 DevOps 理念引入机器学习工程,通过自动化流水线、实验跟踪和资源调度,让模型迭代可靠、可复现、可扩展。
学习目标
学完本章,你将能够:
- 理解 MLOps 生命周期与可复现性、自动化、可观测性三大原则
- 掌握 MLflow 实验跟踪、模型注册与 Staging / Production 版本流转
- 掌握 Kubeflow Pipelines 的 DAG 流水线定义与组件幂等设计
- 理解 SLURM 作业提交、分区调度与 --gres GPU 资源请求
- 掌握 NVIDIA GPU Operator 的设备注册与 MIG 资源切分
- 掌握 DCGM + Prometheus 的 GPU 监控与训练作业的健康保障
前置知识
- 6.12:AI 基础设施 AI 基础设施——GPU、CUDA 与模型服务部署
- ai_llm01 LLM 自托管方案——ollama 与本地推理生产配置
- 6.2:Kubernetes 入门 Kubernetes 容器编排入门——Pod 调度与资源请求
- 5.2:Docker 生产实践 Docker 生产实践——多阶段构建与资源限制
一、MLOps 概念与生命周期
MLOps(Machine Learning Operations)是一套实践体系,核心关注点包括:
- 可复现性:固定代码版本、数据版本、超参数、随机种子,确保同一实验可重复
- 自动化:训练流水线、模型评估、部署上线全流程自动化
- 可观测性:训练指标实时监控,数据漂移与模型退化预警
- 协作:团队共享实验结果、模型版本、部署状态
数据采集 → 数据预处理 → 特征工程 → 模型训练 → 模型评估 → 模型注册 → 部署推理 → 监控反馈
↑ ↓
└──────────────────────── 模型迭代 / 数据漂移修复 ←──────────────────────────────┘
二、MLflow 实验跟踪与模型注册
MLflow 是开源的 ML 生命周期管理平台,核心组件包括 Tracking(实验跟踪)、Models(模型打包)、Registry(模型注册)。
# 启动 MLflow Tracking Server
mlflow server --host 0.0.0.0 --port 5000
# 生产环境:PostgreSQL + S3 后端
mlflow server \
--backend-store-uri postgresql://mlflow:password@db-host/mlflow \
--default-artifact-root s3://mlflow-artifacts/ \
--host 0.0.0.0 --port 5000
在代码中记录实验
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
mlflow.set_tracking_uri("http://mlflow-server:5000")
mlflow.set_experiment("iris-classification")
with mlflow.start_run(run_name="rf-iris-v1"):
params = {"n_estimators": 100, "max_depth": 5, "random_state": 42}
model = RandomForestClassifier(**params)
model.fit(X_train, y_train)
mlflow.log_params(params)
mlflow.log_metric("accuracy", model.score(X_test, y_test))
mlflow.sklearn.log_model(model, "model", registered_model_name="iris-rf")
模型注册与版本管理
# 通过 MLflow CLI 管理模型版本
mlflow models transition -v 1 -s Staging -n iris-rf
mlflow models transition -v 1 -s Production -n iris-rf
# Python API
from mlflow.tracking import MlflowClient
client = MlflowClient()
client.transition_model_version_stage(name="iris-rf", version=1, stage="production")
# 加载 Production 模型
model = mlflow.sklearn.load_model("models:/iris-rf/production")
实验对比与模型服务
# 命令行对比多次运行的指标(UI 中亦可逐项勾选对比)
mlflow experiments list
mlflow runs list --experiment-id 1 --view-type active
mlflow runs compare 2a1b3c4d5e 6f7a8b9c0d
# 把注册的模型直接起 HTTP 服务(本地验证,部署前必做)
mlflow models serve -m models:/iris-rf/production -p 5001
# curl 请求预测
curl -X POST http://localhost:5001/invocations \
-H 'Content-Type: application/json' \
-d '{"dataframe_split": {"columns": ["sepal_length", "sepal_width", "petal_length", "petal_width"], "data": [[5.1, 3.5, 1.4, 0.2]]}}'
# 常用查询 API:按指标筛选历史实验
from mlflow.tracking import MlflowClient
client = MlflowClient()
runs = client.search_runs(
experiment_ids=["1"],
filter_string="metrics.accuracy > 0.85",
order_by=["metrics.accuracy DESC"],
)
for r in runs:
print(r.info.run_id, r.data.metrics.get("accuracy"))
三、Kubeflow Pipelines——K8s 上的 ML 工作流
Kubeflow 在 Kubernetes 上运行 ML 工作流。Kubeflow Pipelines 允许用 Python 定义 DAG 形式的训练流水线,每个节点是一个容器化组件。
# 安装 Kubeflow Pipelines
kubectl apply -f https://github.com/kubeflow/pipelines/releases/latest/download/kfp-pipeline-minimal.yaml
kubectl port-forward -n kubeflow svc/ml-pipeline-ui 8080:80
定义训练流水线
import kfp
from kfp import dsl
@dsl.pipeline(name="training-pipeline", pipeline_root="s3://pipeline-artifacts/")
def training_pipeline(dataset_path: str, epochs: int = 10):
data = data_prep_op(data_path=dataset_path)
training = train_op(train_data=data.outputs["train_csv"], epochs=epochs)
evaluate_op(model=training.outputs["model"], test_data=data.outputs["test_csv"])
# 提交运行
client = kfp.Client(host="http://ml-pipeline.kubeflow.svc.cluster.local:8888")
client.create_run_from_pipeline_func(
training_pipeline,
arguments={"dataset_path": "s3://data/bank.csv", "epochs": 20}
)
Kubeflow 平台组件详解
Kubeflow 是一组相互独立的组件,可按需安装,核心组件与分工如下:
| 组件 | 作用 | 典型场景 |
|---|---|---|
| Kubeflow Pipelines | DAG 流水线编排,记录每次运行的实验与参数 | 端到端训练工作流 |
| Notebook Server | 浏览器中的 Jupyter 环境,支持申请 GPU 配额 | 数据探索、特征分析 |
| Katib | 超参数调优,内置随机搜索 / 贝叶斯 / TPE 算法 | 寻找最优超参数组合 |
| Training Operator | PyTorch / TF / XGBoost 分布式训练 CRD | 多卡多机分布式训练 |
| KServe(原 KFServing) | 模型推理服务,支持自动扩缩容与金丝雀 | 在线推理发布 |
| Central Dashboard | 统一入口与 RBAC 管理 | 团队门户 |
# Katib 超参数调优实验示例
apiVersion: kubeflow.org/v1beta1
kind: Experiment
metadata:
name: rf-hp-tuning
namespace: kubeflow
spec:
objective:
type: maximize
objectiveMetricName: accuracy
algorithm:
algorithmName: bayesianoptimization
parameters:
- name: n_estimators
parameterType: int
feasibleSpace: { min: "50", max: "500" }
- name: max_depth
parameterType: int
feasibleSpace: { min: "3", max: "20" }
trialTemplate:
spec:
containers:
- name: trial
image: registry.local/ml/train:latest
command: ["python", "train.py"]
四、SLURM GPU 集群调度
SLURM 是 HPC 领域最常用的作业调度系统,广泛部署在 GPU 训练集群中,支持节点池管理、GPU 资源预留、作业优先级队列、资源配额等。
关键配置
# /etc/slurm/slurm.conf 关键段落
ClusterName=mycluster
ControlMachine=slurm-master
# GPU 节点定义(Gres=gpu:a100:8 表示每节点 8 块 A100)
NodeName=gpu-[01-04] CPUs=64 RealMemory=256000 Gres=gpu:a100:8 State=ALL
PartitionName=gpu-part Nodes=gpu-[01-04] Default=YES MaxTime=INFINITE
提交 GPU 训练作业
#!/bin/bash
#SBATCH --job-name=train-bert
#SBATCH --partition=gpu-part
#SBATCH --nodes=2
#SBATCH --gres=gpu:a100:8
#SBATCH --time=24:00:00
module load cuda/12.2 cudnn/8.9
export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n1)
export MASTER_PORT=29500
srun python train.py \
--model bert-base-chinese --distributed \
--master-addr $MASTER_ADDR --master-port $MASTER_PORT
常用命令
| 命令 | 说明 |
|---|---|
sbatch job.sh | 提交批处理作业 |
squeue -u $USER | 查看当前作业状态 |
squeue -p gpu-part | 查看 GPU 分区作业队列 |
scancel <jobid> | 取消作业 |
sinfo | 查看集群节点与分区状态 |
srun --gres=gpu:2 bash | 交互式获取 2 块 GPU 的 Shell |
sacct -j <jobid> | 查看已完成作业的资源使用 |
作业生命周期管理
# 提交作业——输出 JobID
$ sbatch train-job.sh
Submitted batch job 482913
# 查看队列——关注 STATE 列:PENDING / RUNNING / COMPLETED / FAILED / CANCELLED
$ squeue -u alice
JOBID PARTITION NAME USER ST TIME NODES NODELIST
482913 gpu-part train-ber alice R 1:23:45 2 gpu-[01-02]
# 作业迟迟不调度——查看原因(QOS 配额 / 资源不足 / 依赖未完成)
$ scontrol show job 482913 | grep -E "Reason|QOS|Priority"
# 常见原因:Resources(节点被占)、Priority(低优先级排队)、
# QOSMaxGpuPerUserLimit(用户 GPU 配额超限)
# 取消作业(先用 TERM 信号让脚本保存 checkpoint,再 SIGKILL)
$ scancel 482913
$ scancel -s TERM 482913 # 优雅终止,训练脚本需处理 SIGTERM
$ scancel -u alice # 取消该用户全部作业(谨慎操作)
# 作业结束后查看资源使用(GPU 利用率、显存、内存峰值)
$ sacct -j 482913 --format=JobID,State,Elapsed,AllocTRES%35,MaxRSS,ExitCode
module load 加载正确的 CUDA/cuDNN 版本,并确保 slurm.conf 中 Gres 声明与物理 GPU 数量一致。
五、Kubernetes GPU Operator(NVIDIA)
NVIDIA GPU Operator 将 GPU 驱动、nvidia-container-toolkit、设备插件、监控组件打包为 K8s Operator,一键简化 GPU 管理。
# 安装 GPU Operator
helm repo add nvidia https://nvidia.github.io/gpu-operator && helm repo update
helm install gpu-operator nvidia/gpu-operator \
--namespace gpu-operator --create-namespace \
--set driver.enabled=true --set toolkit.enabled=true
# 验证
kubectl get pods -n gpu-operator
kubectl get nodes -o json | jq '.items[].status.allocatable["nvidia.com/gpu"]'
申请 GPU 资源
apiVersion: v1
kind: Pod
metadata:
name: gpu-training-pod
spec:
containers:
- name: trainer
image: nvcr.io/nvidia/pytorch:23.10-py3
resources:
limits:
nvidia.com/gpu: 4
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
MIG 与监控
# 启用 MIG(A100/H100 支持,将一块 GPU 切分为多个实例)
kubectl label nodes gpu-node1 nvidia.com/mig.config_1=1g.10gb
# Pod 中使用:nvidia.com/mig-1g.10gb: 2
# 安装 DCGM Exporter 导出 GPU 指标到 Prometheus
helm install dcgm-exporter nvidia/dcgm-exporter --namespace gpu-operator
# 关键指标:DCGM_FI_DEV_GPU_UTIL、DCGM_FI_DEV_FB_USED、DCGM_FI_DEV_MEMORY_TEMP
安装后验证与时间切片
# 进入 GPU 节点执行 nvidia-smi,确认驱动由 GPU Operator 注入
kubectl get pods -n gpu-operator -o wide # 找到 nvidia-driver-daemonset Pod
kubectl exec -it -n gpu-operator nvidia-driver-daemonset-xxxxx -- nvidia-smi
# 输出示例:Driver Version 550.54.15 / CUDA Version 12.4 / 8x NVIDIA A100-SXM4-40GB
# 节点层验证 GPU 可分配数量
kubectl get nodes -o json | jq '.items[].status.allocatable'
# GPU 冒烟测试 Pod
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: gpu-smoke
spec:
restartPolicy: Never
containers:
- name: smoke
image: nvcr.io/nvidia/pytorch:23.10-py3
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1
EOF
kubectl logs gpu-smoke # 能看到显卡信息即通过
时间切片(Time-Slicing)——MIG 的替代方案
MIG 仅 A100/H100 等少数型号支持。旧卡(V100/T4)或需要更多实例时用时间切片:一块 GPU 按时间片共享给多个 Pod,代价是吞吐下降、显存不隔离。
# 定义时间切片配置并应用到 GPU 节点
kubectl create configmap -n gpu-operator gpu-timeslice \
--from-literal=config.yaml='
version: v1
sharing:
timeSlicing:
resources:
- name: nvidia.com/gpu
replicas: 4
'
kubectl label nodes gpu-node1 --overwrite \
nvidia.com/device-plugin.config=gpu-timeslice
# Pod 照常声明 nvidia.com/gpu: 1,但会与其它 Pod 共享同一物理卡时间片
# 对比:
# MIG → 物理隔离,性能可预期(1g.10gb / 3g.40gb)
# 时间切片 → 轻量、无隔离,适合推理占满率低的场景
六、工具选型对照
| 维度 | MLflow | Kubeflow | SLURM | GPU Operator |
|---|---|---|---|---|
| 定位 | 实验跟踪 + 模型管理 | ML 工作流编排 | HPC 作业调度 | GPU 驱动与设备管理 |
| 运行环境 | 任意 Python 环境 | Kubernetes | 裸金属 / VM | Kubernetes |
| GPU 感知 | 否(记录指标) | 通过 Resource Request | 原生 Gres 支持 | 原生 NVIDIA 支持 |
| 适用阶段 | 训练实验 + 模型管理 | 端到端流水线 | 大规模离线训练 | GPU 集群基础层 |
| 学习曲线 | 低 | 中高 | 中等 | 低 |
七、模型部署方案对比
| 方案 | 定位 | 自动扩缩容 | 金丝雀/多版本 | 适用场景 |
|---|---|---|---|---|
| KServe | K8s 原生推理平台(Knative 驱动) | 按 QPS 自动伸缩到零 | 原生支持流量切分 | K8s 内的生产推理、大模型服务 |
| Seldon Core | 推理图编排(多模型组合、外呼预处理) | 支持(HPA / 自定义指标) | 原生支持 | 复杂推理流程、AB 测试 |
| BentoML | 模型打包 + 服务化(Yatai 管理平台) | 依赖 K8s/Knative 适配 | 部分支持 | 从 Python 服务快速起步、团队小 |
MLOps 成熟度模型
| 等级 | 特征 | 工具栈 |
|---|---|---|
| L0 - 手动 | 手动训练、手动部署、无版本管理 | Jupyter Notebook |
| L1 - 基础自动化 | 实验跟踪、模型注册、自动化训练 | MLflow + Airflow |
| L2 - CI/CD | 自动化流水线、模型评估、自动部署 | Kubeflow + Argo CD |
| L3 - 可观测 | 数据漂移监控、模型性能追踪、自动再训练 | + Prometheus + Evidently |
| L4 - 全自动 | 端到端自动化、A/B 测试、渐进式发布 | + KServe + Argo Rollouts |
八、MLOps 端到端流水线示例
把前文各环节串成一个完整的训练-发布闭环(数据 → 训练 → 注册 → 部署 → 监控):
# 阶段 1:数据验证与版本化(校验 schema + 打数据快照,记录 hash)
# 阶段 2:训练并记录到 MLflow(参数、指标、git_commit、数据 hash 全部入库)
python train.py --data s3://data/v1.3/bank.csv \
--mlflow-uri http://mlflow-server:5000 --experiment churn-model
# 阶段 3:评估通过 → transition 到 Staging
mlflow models transition -v 3 -s Staging -n churn-model
# 阶段 4:部署到 KServe(注册模型版本作为推理入口)
kubectl apply -f - <<EOF
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
name: churn-model
spec:
predictor:
model:
modelFormat:
name: sklearn
storageUri: s3://mlflow-artifacts/3/churn-model/artifacts/model
resources:
requests:
cpu: 500m
memory: 1Gi
EOF
# 阶段 5:监控——Prometheus 采集推理延迟/QPS,业务侧计算 PSI 数据漂移指标
# 阶段 6:漂移超阈值触发重新训练 → 回到阶段 1(MLflow 记录新数据集 hash)
常见错误
- MLflow 实验间 artifacts 互不可见——默认
mlflow server使用本地mlruns/目录存储。多 Worker 场景必须配置共享后端(PostgreSQL + S3/MinIO),否则各节点只看到自己的实验记录。 - Kubeflow Pipeline 组件执行报 OOMKilled——组件容器未声明
resources.requests/limits,调度器分配了过小内存。在组件装饰器中显式设置set_cpu_request/set_memory_limit,并根据数据集大小合理估算。 - SLURM 作业提交后 Pending 不调度——常见原因:① 分区资源耗尽(
sinfo检查 Idle/GPU 空闲数)② 账户未配置 QOS 或 fairshare 配额超限 ③--gres请求的 GPU 类型与节点声明不匹配。 - K8s Pod 无法获取 GPU 资源(nvidia.com/gpu: Insufficient)——检查 GPU Operator 是否正常运行,节点
nvidia.com/gpu是否已注册(kubectl describe node | grep nvidia.com/gpu),以及是否有 toleration 匹配 GPU 节点的 taint。 - 模型训练指标在 MLflow 中丢失——
mlflow.log_metric必须在mlflow.start_run()的上下文内调用;如果启用了异步日志(环境变量MLFLOW_ENABLE_ASYNC_LOGGING=true),需在训练结束前调用mlflow.end_run()或mlflow.flush_async_logging()刷盘。
最佳实践
- 固定一切以保证可复现性——在 MLflow 中同时记录
git_commit、数据集 hash、随机种子和框架版本,确保任何人从同一 run ID 都能完整还原训练环境。 - 流水线组件保持幂等——Kubeflow Pipeline 的每个组件应支持重复执行而不产生副作用:数据预处理组件先去重再写入,训练组件用固定 output path 覆盖而非追加。
- GPU 资源按需切分——对于推理服务等轻量任务,启用 NVIDIA MIG(Multi-Instance GPU)将一块 A100 切分为 1g.10gb / 3g.40gb 等多个实例,提高 GPU 利用率;大规模训练则独占整卡。
- 监控先行再上训练——部署 DCGM Exporter 到 GPU Operator,先接好 Prometheus + Grafana 看板(GPU 利用率、显存占用、温度),再去提交长时间训练作业,避免 GPU 故障时无人察觉。
- 模型注册后自动触发评估——在 MLflow Registry 中设置 Webhook,模型进入 Staging 时自动触发 Kubeflow Pipeline 运行评估任务,评估通过后自动 transition 到 Production。
故障排查案例:SLURM 作业 Pending 不调度
现象:提交 SLURM 训练作业后,squeue -u alice 显示 STATE 列为 PENDING,持续 2 小时未调度。
排查:执行 scontrol show job <jobid> | grep -E "Reason|Priority",输出 Reason: Resources;执行 sinfo -p gpu-part -N -o "%N %T %G",发现所有 GPU 节点状态为 mixed(部分资源被占用),但 Gres 声明的 GPU 数量与实际不符。
根因:slurm.conf 中 NodeName=gpu-[01-04] Gres=gpu:a100:8 声明每节点 8 块 A100,但 gpu-03 节点实际只有 4 块(之前有一块被移除),导致 SLURM 认为该节点有 8 块 GPU 可分配,实际只有 4 块,资源分配冲突。
修复:① 修正 slurm.conf 中 gpu-03 的 Gres 声明为 gpu:a100:4;② 执行 scontrol reconfigure 热加载配置;③ 验证 sinfo -p gpu-part -N -o "%N %T %G" 显示正确的 GPU 数量。
# 查看作业未调度原因
scontrol show job <jobid> | grep -E "Reason|Priority|QOS"
# 查看节点资源使用情况
sinfo -p gpu-part -N -o "%N %T %C %G"
# 查看用户 GPU 配额
sacctmgr show assoc user=alice format=User,Cluster,QOS,MaxTRES
# 热加载 slurm.conf(无需重启 slurmd)
scontrol reconfigure
scontrol update nodename=gpu-03 gres=gpu:a100:4
squeue 确认 STATE → ② scontrol show job 查看 Reason → ③ sinfo 检查节点资源 → ④ sacctmgr 检查 QOS/fairshare 配额 → ⑤ 检查 slurm.conf Gres 声明与物理设备一致性。MLflow 实验数据漂移检测
# 在 MLflow 中记录训练数据的统计特征(用于后续漂移检测)
import mlflow
import numpy as np
with mlflow.start_run(run_name="churn-model-v1"):
# 记录训练数据分布特征
mlflow.log_metric("data_mean_age", np.mean(X_train[:, 0]))
mlflow.log_metric("data_std_age", np.std(X_train[:, 0]))
mlflow.log_metric("data_mean_income", np.mean(X_train[:, 1]))
mlflow.log_metric("data_class_balance", np.sum(y_train) / len(y_train))
# 训练完成后记录模型性能
mlflow.log_metric("accuracy", accuracy)
mlflow.log_metric("f1_score", f1)
# 在推理服务中监控数据漂移(PSI 指标)
# 当 PSI > 0.2 时触发重新训练
from scipy.stats import ks_2samp
stat, p_value = ks_2samp(reference_data, current_data)
if p_value < 0.05:
print("数据分布发生显著漂移,建议重新训练模型")
练习题
- 编写一个 MLflow 实验脚本:使用 scikit-learn 的 Wine Quality 数据集训练一个 GradientBoosting 模型,记录 3 组不同的
max_depth和learning_rate超参数组合,比较准确率和 F1 分数,将最优模型注册到 Model Registry 并 transition 到 Staging 阶段。写出完整 Python 代码。 - 设计一个 SLURM 提交脚本:在 4 节点 A100 集群上使用 PyTorch DDP 训练 BERT,要求脚本包含 CUDA/cuDNN 模块加载、NCCL 环境变量设置、梯度累积(每 4 步更新一次)、以及训练完成后自动将 checkpoint 上传到 S3。写出脚本并解释每个
#SBATCH参数的含义。 - 在 Kubernetes 上使用 GPU Operator 部署一个推理服务:编写 Deployment YAML,申请 1 块 GPU,配置健康检查(liveness + readiness probe),设置资源 requests/limits,并说明如何通过
kubectl top nodes和 DCGM 指标验证 GPU 是否被正确分配和使用。
学习检查点
学完本章后,请检验自己是否掌握以下内容:
| 检查项 | 自测问题 | 验证方法 |
|---|---|---|
| 概念理解 | 能用自己的话解释 MLOps 的流水线和模型版本管理 | 尝试向他人讲解 |
| 命令操作 | 能不查文档完成 MLflow/Kubeflow 部署和实验追踪 | 在终端实际执行 |
| 原理掌握 | 能说出模型训练、评估、部署的自动化流水线原理 | 画出流程图 |
| 故障排查 | 能独立排查模型训练失败或模型服务性能下降的问题 | 模拟故障并修复 |
| 最佳实践 | 能说明为什么需要为 ML 模型配置 A/B 测试和灰度发布 | 对比不同方案 |
本章总结
MLOps 的本质是流程而非工具:MLflow 管实验与模型版本,Kubeflow 编排训练流水线,SLURM 与 GPU Operator 调度稀缺算力。可复现性来自固定代码、数据与超参数,可靠性来自先接监控再跑训练。
MLOps 工具选型决策树
你需要什么?
│
├─ 实验跟踪 + 模型管理
│ └─ MLflow(轻量、独立、易上手)
│
├─ 端到端 ML 流水线
│ ├─ 已有 K8s → Kubeflow Pipelines
│ └─ 无 K8s → MLflow + Airflow / Prefect
│
├─ GPU 集群调度
│ ├─ HPC 场景 → SLURM
│ └─ K8s 场景 → GPU Operator + Volcano
│
├─ 模型推理部署
│ ├─ K8s 生产环境 → KServe
│ ├─ 多模型编排 → Seldon Core
│ └─ 快速原型 → BentoML
│
└─ 全托管方案
└─ SageMaker / Vertex AI / Azure ML
延伸阅读
- MLflow 官方文档:https://mlflow.org/docs/latest/index.html
- Kubeflow Pipelines 官方文档:https://www.kubeflow.org/docs/components/pipelines/
- SLURM 官方文档:https://slurm.scheddocs.com/
- NVIDIA GPU Operator GitHub:https://github.com/NVIDIA/gpu-operator
- NVIDIA DCGM:https://docs.nvidia.com/datacenter/dcgm/latest/
- Google MLOps 白皮书:https://cloud.google.com/architecture/mlops-continuous-delivery-and-automation-pipelines-in-machine-learning
- Chip Huyen《Designing Machine Learning Systems》——MLOps 领域经典参考书