首页 用户案例 造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层

造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层

存算分离的阿里云环境下,自动驾驶模型训练面临 OSS 数据访问延迟高、GPU 利用率不足的普遍挑战。造父智能(哈啰robotaxi)基于 Alluxio 构建了一套对用户完全透明的训练数据加速层:平台自动完成 OSS Bucket 到 Alluxio UFS 的注册,根据队列节点类型智能选择挂载策略(CSI Ephemeral / Sidecar FUSE / PVC),训练 Pod 内仅可见标准 POSIX 路径,数据加速与缓存管理对用户完全不可见。本文将剖析 Alluxio 加速层从架构设计到生产落地的完整过程,涵盖 UFS 自动化管理、多策略挂载翻译引擎、跨命名空间 PVC 同步、多云凭证治理等已落地的核心实践。
造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层

 

关于作者

管宪良,造父智能(哈啰robotaxi) AI-Infra 超算平台架构师。主导设计并落地覆盖 20+ 微服务的全栈训练平台,负责资源编排中枢、多集群数据资产管理、Alluxio  分布式缓存深度集成等核心模块。在存算分离架构下的训练数据加速、多云统一数据访问、K8s 云原生调度等领域有丰富实战经验。

 

关于造父智能

造父智能是哈啰出行旗下自动驾驶公司,聚焦 Robotaxi 领域。公司以全栈自研的自动驾驶技术为核心,覆盖感知、规划、控制等关键模块,致力于打造安全、高效的无人驾驶出行服务。目前已在多个城市开展路测与试运营,持续推进  L4 级自动驾驶的规模化落地。

业务场景与核心挑战

造父智能(哈啰robotaxi)在阿里云上进行自动驾驶训练的场景介绍

自动驾驶行业有个共性特点,就是训练的数据量特别大,造父智能(哈啰robotaxi)是以对象存储作为训练底座,在 GPU 训练的过程中普遍存在 I/O 瓶颈,这些都是比较常见的问题。而现在的场景有三层叠加的约束:
多云存储:同时使用多个公有云的对象存储,比如阿里云的 OSS,百度的 BOS,每个公有云的 SDK、IAM 体系和 endpoint 都不一样;
节点异构:架构中既有普通的物理 GPU 节点,又有很多阿里云 ACS 这类 Serverless GPU 节点,这类 Serverless 节点集群层安装不了 CSI Driver,不能用原生 CSI 方式使用 Alluxio,因此需要用其他方式对接 Alluxio;
多 Namespace 强隔离 + 共享数据:业务按团队切分 Namespace(以下简称:NS),同一份数据集可能在多个 NS 下都会使用,比如感知团队、端到端团队,团队使用多个 NS 的方式进行资源切分,但是 Alluxio 原生 PVC 没有跨多个 NS 同步的机制。
最复合的场景就是 Serverless GPU 节点在业务 NS 上挂载 PVC,并挂载同一份 OSS 数据集。在这三种约束叠加的情况下,Alluxio 原生的部署方式无法覆盖。

整体架构总览

目前造父智能(哈啰robotaxi)采用的是 5 层数据流架构,用户在训练层只能看到数据集这种虚拟的定义,完全不感知数据在底层存储的实际位置,架构提供 Web 入口、CLI、SDK 供用户做数据集管理和任务提交,用户访问路径是统一的 /mnt/datasets/… POSIX 语义。

五层数据流架构

造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层
核心架构是 Alluxio 加速层和 asset-api 编排层的配合设计:
asset-api 层:通过数据资产编排中枢,实现了UFS自动注册、挂载翻译引擎、Alluxio CSI自愈、跨NS PVC同步这几个核心能力;
Alluxio 企业版:作为核心缓存加速层,挂载底层的存储,通过 Alluxio 自己的 CSI Driver、FUSE、Cache 以及 CSI 自愈能力,实现训练 I/O 的直接加速;
底层存储:多云异构的持久化存储,包括 S3/OSS/GCS、CPFS、NAS 等。

核心能力框架

在明确了整个架构图的分布后,可以具体看下造父智能(哈啰robotaxi)的技术架构从工程层面与 Alluxio 在 Kubernetes 的实际整合,核心包括:

4点摘要对齐:

✓UFS 的自动注册与生命周期管理:将原生静态声明扩展为业务 CRD 驱动的动态注册;
✓多策略挂载翻译引擎:将原生 CSI 假设节点同质扩展为异构节点上的策略抽象;
✓subpath 失效与 CSI Ephemeral 自愈:突破 FUSE 自愈止于 bind-mount 寿命的边界,使用 CSI Ephemeral 重取控制权;
✓跨 NS PVC 自动同步:Alluxio 是有 StorageClass 集群层面的控制,补齐 K8s 原生缺失的 NS 级 PVC 分发机制。

3条生产经验:

✓多云凭证治理;
✓路径规范化;
✓队列灰度。

核心技术方案

UFS自动注册:从声明式到编排式的演进

Alluxio 企业版原生提供 UnderFileSystem CRD;支持动态手动声明,如 path、mountPath、mountOption 这些参数,在 Alluxio 上静态场景下是很简洁的声明方式; mountOptions 核心是 accessKey 和 endpoint;多 bucket对应多 CRD;多云对应多套凭证前缀等,但在造父智能(哈啰robotaxi)的生产场景有一些约束:
✓造父智能(哈啰robotaxi)现在的数据集生命周期完全由业务自助闭环,超算团队不需要介入,业务自助创建、下线数据集的频率非常高;
✓凭证比如 AK/SK 这一层是从平台侧统一配置中心下发的,业务完全不感知;
✓多云的 mountOption 差异对业务来说是完全封装的,业务只知道 bucket 的名字,并不感知下面的云厂商类型。
解决方案:在平台层做了扩展,定义业务侧的 Storage CRD,仅需要填写 bucket、storageType、cluster 三个字段,asset-api 自动根据 storageType 切换 mountOptions 前缀,读取对应凭证,自动生成 Alluxio UFS CR 并拉起服务。
造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层
扩展到多家公有云时,改动点仅一处:在 mountOptions 构建逻辑的 switch 里新增一行 case 分支即可,底层 SDK、配额、endpoint 差异仍然存在,但 mountOptions 层抽象保持稳定。如果我们要扩展支持新的公有云,只需要加这一行代码,用户就可以在多云场景下无缝使用多个公有云的存储。
造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层

 


挂载策略翻译:节点异构长期约束下的策略抽象

我们的三类节点对应三种可行的挂载方式:
造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层
物理 GPU 节点:这是最常用也是首选的方式,可装 CSI Driver,首选 CSI Ephemeral Inline Volume;它在 Kubernetes 中是完整的 Node 节点,与 Alluxio 的适配是最好的,只需要部署 Alluxio 的专属 operator 就可以直接走 CSI 的挂载方式,直接在物理 GPU 上实现数据访问加速;
Serverless GPU(阿里云 ACS 等):尤其现在 H20 这类 GPU 采购还是非常困难的,阿里云上提供的 Serverless GPU,集群层不支持 CSI Driver,所以并不能采用 Alluxio operator 的部署方式,唯一可选的方案就是 Sidecar FUSE 容器的方式,把 Alluxio FUSE 客户端作为 Sidecar 容器注入到用户的训练 Pod 里。
老集群兼容期/共享训练节点:可装 CSI 但历史上不走 CSI,用共享 PVC + subpath。这是老集群兼容的场景,团队用传统的 PVC + subpath 的形式,通过 PVC 上的 subpath 区分各个数据集之间的权限边界。
团队最开始的方案是在 Alluxio 集群中把所有阿里云的对象存储都挂载进去,暴露给用户的是完整的根路径,用户可以自由读取所有对象存储的数据,没有任何权限限制。后来演进到用 subpath 的形式来划分各个数据集的边界,但用 PVC 和 subpath 的方式也会遇到一些问题,所以我们后来就演进到了优先用 CSI 的方式,FUSE 进程如果挂掉的话, CSI 会自动重建,不会影响训练。团队在挂载策略翻译上的核心设计判断为:挂载策略是队列属性,而非数据属性,这也是整个翻译引擎的设计基础。数据集本身不具备挂载策略属性,也无相关策略字段,挂载方式由 Pod 的调度目标决定;如果将策略绑定到数据集,同一数据在不同队列需要不同策略时,会出现维护失控的问题。当前调度策略以队列为核心,不同队列对应不同机型,团队直接在队列上绑定对应的挂载策略,用户选定队列即选定策略:
✓普通 H20 物理节点的队列,采用 CSI 方式;
✓Serverless GPU 的队列,采用 sidecar 方式;
✓像阿里云 5880 这类暂不支持 CSI 的老节点 PVC  队列,则采用 PVC 的 subpath 方式。
通过将所有挂载策略绑定在队列上,实现了根据不同队列场景灵活适配挂载方式的目标。
造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层
挂载翻译引擎采用纯函数设计,核心函数 Translate 接收  Mount 和 Params 参数,返回 Volume 和 VolumeMount 列表,通过 switch 分支实现三种挂载策略。该设计无外部依赖,HTTP/DB/ 配置中心均由调用方注入,三种策略对应独立的分支,彼此可独立测试;团队后续在新增节点或存储类型时,只需新增分支,不影响既有逻辑,天然具备确定性、无副作用、可独立演进的特性。团队可通过单队列灰度验证的方式,在独立队列上迭代、测试不同的挂载策略。


三种策略的适用域与代价:

CSI Ephemeral:NodePublish 对齐 Pod 生命周期,FUSE 异常时 NodePublish 自动重建,是物理 GPU 节点首选,前置依赖是节点可安装 CSI Driver;
Sidecar 方式:用 emptyDir 共享卷加 fuse-device hostPath,业务容器开启 mountPropagation: HostToContainer,是 Serverless 节点的唯一可行方案,开销是额外容器、生命周期耦合;
共享 PVC + subpath 方式:单 PVC 多任务共享,运维成本最低,兼容历史集群,代价是隔离性弱、subpath 生命周期风险。
此外,团队观察到节点异构的长期趋势:Serverless GPU(阿里云ACS/腾讯EKS on CVM等)、Virtual Kubelet、Spot GPU、K8s 虚拟节点,共同特征是节点不可安装 Alluxio 原生提供的 CSI Driver。从实际生产场景发现,这类虚拟 K8s 节点的占比从今年上半年到现在越来越高,CSI 的方式在 Kubernetes 中肯定是最优雅的存储接入方式,但对于这类非原生 Kubernetes 节点的场景,CSI 的前置假设越来越不成立了,这块值得更多的共同探讨。


subpath 失效与 CSI Ephemeral 自愈:突破 FUSE 自愈边界

团队在实际使用中遇到过最头疼的问题就是“静默 Hang”,训练 Pod 通过 FUSE 挂载训练数据集,通过 subpath 映射成子目录,FUSE 客户端重启之后,Alluxio 侧会重新拉起 FUSE 客户端,重新注册挂载点到业务容器中,但在业务容器里 ls 这个 subpath 路径,返回的结果全是空的,训练脚本就直接 Hang 在数据读取环节。这种问题不报错、无日志、链路全绿,仅在数据读取点停摆,排查成本极高。


根因分析:问题在 bind-mount 层

团队在长期 debug 之后发现根因是:Kubelet 在容器里用 bind-mount 实现 subpath,bind-mount 会持有源路径的 inode,当原挂载点 umount 后重建之后 inode 发生变更, bind-mount 就会失效,不会自动重连。Alluxio 的自愈作用域仅限于 FUSE 挂载点之内,bind-mount 层是 Kubelet 的逻辑,不在 Alluxio 的控制视角之内。Alluxio 层的所有挂载操作都是完全正确的,但 Kubelet 不能把重新挂载的挂载点更新到业务容器里。


解决方案:对齐 Pod 生命周期

造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层
团队现在的解决方案是弃用静态 subpath,使用 CSI Ephemeral Inline Volume,不再预先声明静态 Volume,直接在 Pod 的 Volume 字段声明 CSI 类型卷,当 FUSE 异常的时候,CSI 的 NodePublish 会直接把新的挂载点传递到业务容器里,业务容器会立刻感知到挂载点变更,自动重新挂载。这个方案的适用域是短生命周期任务 Pod,不适用于长期运行的 infra Pod。


跨 NS PVC 自动同步:补齐 K8s 原生分发机制

K8s 原生 StorageClass 模式的前提假设是:每个业务 NS 必须预置一份 Alluxio PVC。用户在业务 NS 创建 PVC,StorageClass provisioner 接收请求动态供给 PV,PV 绑定 PVC 后 Pod 挂载 PVC。这个前提源于 K8s 的设计约束,PVC 是 namespaced 对象,与 Alluxio 无关。K8s 原生的 StorageClass 是集群级资源,但 PVC 是命名空间级对象,跨 NS 分发的能力是原生缺失的,团队实现了 NS 级的 PVC 分发方式。一开始只会在系统命名空间下创建一个模板 PVC,但业务层面有 20 多个 NS,每个 NS 都需要对应的 Alluxio PVC。


解决方案

平台层在专属的 Alluxio NS 下维护一个 PVC 模板,通过 Label 标记需要同步,我们的挂载引擎会定时扫描模板,把 PVC 复制到所有的业务 NS。团队只做 PVC 的复制,PVC 上声明的是 Alluxio 的 StorageClass,PV 的创建仍然由 Alluxio StorageClass 自动处理,平台并不介入 PV 的创建和管理。设计约束是仅做 NS 间 PVC 复制,不修改 PV,因为手工修改 PV 的 ClaimRef/VolumeHandle,错误后果为静默的数据错乱,风险不可承担。这个方案的代价是业务 NS 新建至 PVC 可用最大有 1 分钟延迟,换取的是业务 NS 无感知、同步逻辑可独立演进,同时创建 NS 本身是低频操作,并不会影响到业务的使用。


生产实践经验

多云凭证治理

造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层
造父智能(哈啰robotaxi)的多云凭证管理演进了三个版本:最开始是单 endpoint 维度,造父智能(哈啰robotaxi)在上海的一个 region,对应单一的 OSS 对象存储;后面演进到多集群 endpoint 的方式,因为团队发现单集群的计算节点不够用了,就引入了多集群共享同一个 OSS 的模式;第三个版本是 OSS 已经不能满足业务的存储需求,团队就引入了其他公有云的对象存储,变成了多云多集群的混合模式。
造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层
团队封装了统一的 ResolveS3Key 函数,调用方无需关心优先级规则,内部封装 cluster 优先 + endpoint 兜底的逻辑。这是典型的 “场景后追加” 问题,关键在于容纳历史的抽象设计,而非推倒重来。


路径规范化

造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层
团队现在在路径层面做了三层统一:Pod 层面的 CSI subpath、Alluxio 侧的 UFS 挂载点、对象存储侧的 bucket 和 prefix 方式,三者的路径规则完全统一,实现了多云多集群存储策略的完全对齐。如果不统一会导致跨模块的静默读写不一致,排查成本极高。路径规范化属于平台级约定,不下放到各层各自处理。


队列级灰度

遵循默认回退 + 显式 override 原则:队列灰度就像前文提及的,团队现在是用 volcano 进行调度,调度以 queue 为核心,通过显式修改队列的挂载策略,就可以适配多种异构 GPU 节点的场景。当新的异构节点上线的时候,可以灵活选择用哪种方式对接 Alluxio。


总结与展望

造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层
通过 Alluxio 核心加速层与 asset-api 编排层的配合,团队成功解决了多云异构 GPU 场景下的训练 I/O 瓶颈问题,实现了业务完全不感知底层存储差异的统一数据访问体验,在这个过程中团队逐渐明确了 Alluxio 企业版的边界条件,同时团队也在 K8s 平台层对这些边界做了补位。一句话总结就是:Alluxio 的核心价值是加速,平台的核心价值是把加速层合法接入 K8s 的各类现实约束。两层是配合关系,非竞争关系,平台层的复杂度,完全建立在 Alluxio 核心层的稳定之上。