# 选 ML 流水线平台，先问你走后谁来运维

> 微软把 Kubeflow 列为 Azure ML 流水线的开源对应方案，Vertex 也能直接运行 KFP 代码，功能表已经拉不开差距。

原文: https://fdetimes.net/zh/analysis/kubeflow-sagemaker-vertex-azure-ml-who-operates/

微软在介绍机器学习流水线的官方文档里列了一张对照表，在 Azure Machine Learning 流水线一行的“开源对应方案”一栏填上了 Kubeflow Pipelines。两者面向同一类用户，即数据科学家，覆盖的也是从数据到模型的同一段流程。

一家云厂商主动把开源项目称作自家产品的对应方案。Google 那边，Vertex Pipelines 也能直接运行用 KFP SDK 编写的代码。功能边界模糊到这种程度，逐项比较功能几乎没有意义，决定性的问题转到了别处：你离开客户现场之后，谁来运维这条流水线？

对前线部署工程师（FDE）来说，这不是理论问题。第一条流水线往往由你搭建，但长期与它打交道的不是你。如果选的平台不适合接手的人，流水线再优雅，也会慢慢失修。

## 流水线代码几乎说同一种语言了

先看 Kubeflow。根据其官方代码仓库，Kubeflow Pipelines 是可复用的端到端 ML 工作流，用 KFP SDK 编写，运行在 Kubernetes 上。你声明每个步骤，把上一步的输出接到下一步的输入，再把整体编译成一份流水线定义。

关键在于，这份定义并不绑死在你的集群上。Google 在 2021 年 11 月宣布 Vertex Pipelines 正式可用时明确表示，该服务支持两个开源库：Kubeflow Pipelines 和 TensorFlow Extended。因此，用 KFP 编写的流水线无需重写逻辑，就有路径迁到 Google 的托管服务上。

Azure 也没有置身事外。微软支持通过 CLI、Python SDK 或 Designer UI 构建流水线；在同一张对照表里，Azure ML 流水线和 Kubeflow Pipelines 同处一行，都强调分布式、缓存、代码优先开发和复用。各家厂商用的是一套共同的词汇。

就连最常见的区分也不再鲜明。供应商 JFrog 有自己的立场，它在一篇博客中这样概括：Kubeflow 侧重编排和流水线，SageMaker 更偏向数据科学。这是产品侧重点的差别，而不是客户的流水线能不能跑起来的差别。

## 真正的区别：流水线出故障时谁值班？

重读一遍文档，这次只看其中关于运维者的说法。Kubeflow 仓库写明，KFP 可以作为 Kubeflow Platform 的一部分安装，也可以作为独立服务部署。无论哪种方式，后果都一样：客户那边必须有人负责 Kubernetes 集群，负责升级，并在集群出问题时接收告警。

云厂商的说法正好相反，而且说得很直白。Google 写道，Vertex AI 负责为运行流水线的基础设施做资源供给和扩缩容，客户只为流水线运行期间使用的资源付费，数据科学家可以专注于 ML。

AWS 把 SageMaker Pipelines 描述为专为 MLOps 和 LLMOps 打造的无服务器编排服务，也就是说，客户无需自己运维编排层。

第二个承诺体现在界面上。SageMaker Pipelines 在 SageMaker Studio 中提供拖拽式界面，Azure ML 除了 SDK 和 CLI 还有 Designer UI。厂商设计时考虑的是不想读 YAML 的人，而不只是平台工程师。

Azure ML 文档里还有一句话值得贴在会议室墙上：数据工程师、数据科学家和 ML 工程师各自负责自己的步骤。一条流水线没有唯一的负责人。所以“由谁运维”要拆成三层来问：谁编写步骤，谁修复步骤，谁维持底层机器的运转。

**要点:** 先确定谁为流水线值班，再选适合这个人的工具。

设想两个客户。客户 A 是一家电商公司，有三名数据科学家，跑在 AWS 上，没有人精通 Kubernetes。客户 B 是一家银行，其平台团队运维 Kubernetes 多年，希望所有东西都部署在自有基础设施上。

从功能看，两家用哪个方案都行。从运维者看，A 几乎肯定应该选 SageMaker Pipelines，因为团队里没人扛得住一个集群。B 则有充分理由独立部署 KFP，因为它的平台团队早已习惯为这类系统值班。

AWS 宣传 SageMaker Pipelines 能在生产环境中同时运行数万个 ML 工作流。数字很亮眼，但对客户 A 毫无决定意义，它一天大概只跑几条流水线。更有用的数字是：客户那边有几个人能在半夜读懂一个 pod 的日志。

## 四个方案，按运维者排列

把文档拼在一起，把“由谁运维”一列放在功能列前面，局面就清楚了：

| 方案 | 文档中的运维者 | 提到的流水线构建方式 | 最适合 |
|---|---|---|---|
| Kubeflow Pipelines（独立部署或在 Kubeflow Platform 内） | 客户团队，在自有 Kubernetes 上 | KFP SDK | 已有熟悉 Kubernetes 的平台团队 |
| Vertex Pipelines | Google 负责基础设施的资源供给和扩缩容 | KFP SDK 或 TFX | 想保留 KFP 代码、又不想背集群负担的 GCP 用户 |
| SageMaker Pipelines | AWS，以无服务器编排的方式 | SageMaker Studio 中的拖拽式界面 | 团队较小、不太熟悉基础设施代码的 AWS 用户 |
| Azure ML 流水线 | 数据工程师、数据科学家和 ML 工程师各自负责自己的步骤 | CLI、Python SDK 或 Designer UI | 多个角色共同负责各步骤的 Azure 用户 |

看最后一列就会发现，决定其实在打开任何功能页面之前就已经做出了。客户已经在用的云、已经有的团队，几乎排除了所有其他选项。

## “随时可迁移”的流水线长什么样？

在还不确定谁来运维时，有一招可以降低风险：用 KFP SDK 编写流水线，并让逻辑不依赖任何一家云的专有 API。下面的示例代码只有两个步骤（标识符原为越南语：`clean_data` 意为“清洗”，`train_model` 意为“训练”，`input_data` 意为“输入数据”）：

```python
from kfp import dsl, compiler

@dsl.component(base_image="python:3.11")
def clean_data(input_data: str) -> str:
    # 只处理数据，不调用任何特定云厂商的 API
    return input_data

@dsl.component(base_image="python:3.11")
def train_model(data: str) -> str:
    return "model-uri"

@dsl.pipeline(name="churn-pipeline")
def churn(input_data: str):
    cleaned = clean_data(input_data=input_data)
    train_model(data=cleaned.output)

compiler.Compiler().compile(churn, "churn.yaml")
```

第一个组件中的注释意为：“只处理数据，不调用任何特定云厂商的 API”。

生成的 `churn.yaml` 文件可以在客户平台团队自行运维的 KFP 部署上运行；由于 Vertex Pipelines 支持 KFP，它也有路径迁到 Google 的托管服务。如果六个月后客户决定不想再为集群值班，你改的是运行位置，而不是逻辑。

要保住这个优势，就要把与环境相关的内容，比如存储路径或项目名，拆成传入流水线的参数，而不是硬编码在组件里。到客户现场的第一周，第一件事是在白板上写下流水线失败时接收告警的人的名字，然后再打开 IDE。

## 从岗位描述看谁背呼叫器

同样的能力也能帮你挑岗位。岗位描述里提到 Kubernetes、Helm 和 Kubeflow，通常意味着你或客户会是运维者，要准备好谈集群升级和故障处理。

如果强调 SageMaker Studio、Designer 或与利益相关方协作，则说明你会把工作交给数据科学家，关键能力是让别人也能修得动的设计。

对想转型 FDE 的越南开发者来说，最省钱的练习方式是把同一个 KFP 文件放在两处运行：本地集群和 Vertex Pipelines。简历上不要只列“Kubeflow, SageMaker”，要写清楚你根据哪个团队运维来选择平台，以及交接给了谁。

面试时被问到选哪个工具，可以试着反问：FDE 离开后，流水线出故障时谁会被叫醒？提前练好这个反应，因为工具可能开一次会就换掉，而运维团队才是你必须围绕它来设计的对象。

**本周动手试试:**

- 用 KFP SDK 写一条两步流水线，编译成 YAML 文件，先在本地集群上运行，再把同一个文件原封不动地放到 Vertex Pipelines 上运行。
- 找三份你想投的 FDE 或 ML 工程师岗位描述，标出能看出你是运维者（Kubernetes、Helm、Kubeflow）还是交接者（SageMaker Studio、Designer、利益相关方）的关键词。
- 准备三个关于“谁来运维流水线”的问题，带到下一次客户需求调研或面试中。

## 信源

- [GitHub - kubeflow/pipelines: Machine Learning Pipelines for Kubeflow](https://github.com/kubeflow/pipelines)

- [Announcing Vertex Pipelines general availability](https://cloud.google.com/blog/products/ai-machine-learning/serverless-machine-learning-pipelines-on-google-cloud)

- [Amazon SageMaker Pipelines](https://aws.amazon.com/sagemaker-ai/pipelines/)

- [What are machine learning pipelines? - Azure Machine Learning | Microsoft Learn](https://learn.microsoft.com/en-us/azure/machine-learning/concept-ml-pipelines?view=azureml-api-2)

- [A Brief Comparison of Kubeflow vs. SageMaker](https://jfrog.com/blog/a-brief-comparison-of-kubeflow-vs-sagemaker/)
