华为云 ModelArts 端到端实战:从数据标注到在线推理
引言
很多团队的 AI 项目卡住,并不是模型不够好,而是链路太长:数据在 A 同学的电脑上,训练脚本在 B 同学的服务器上,上线又要找运维从头搭环境。华为云 ModelArts 要解决的正是这个问题——把"数据 → 标注 → 开发 → 训练 → 调优 → 部署 → 运维"收进一个平台。
本文不逐条罗列控制台按钮,而是按真实项目的时间顺序,讲清楚每个环节该做什么、容易踩什么坑。
一、ModelArts 的三种打开方式
| 方式 | 适合人群 | 特点 |
|---|---|---|
| 控制台 / 自动学习 / Workflow | 业务人员、快速验证 | 少写代码,拖拽式编排 |
| Notebook | 算法工程师 | 交互式开发,随开随停 |
| SDK / API / CLI | 平台与后端团队 | 可集成进 CI/CD,便于自动化 |
一条务实的建议:先用 Notebook 把流程跑通,再把稳定下来的代码固化成训练作业,最后用 SDK 接进流水线。反过来做,往往会在环境问题上浪费大量时间。
二、准备工作:OBS 目录规划与权限
ModelArts 的数据与产物主要存放在对象存储服务 OBS 中。项目开始前,先把桶内目录规划好,能省掉后面大量改路径的时间:
my-bucket/
├── dataset/ # 原始数据、标注结果
├── code/ # 训练代码(每次提交作业打一个版本)
├── output/ # 训练产物、checkpoint、日志
└── model/ # 推理模型包(含推理代码)
几个容易忽视的点:
- 区域一致性:OBS 桶与 ModelArts 工作空间尽量在同一个区域,跨区域读写既慢又可能产生额外费用;
- 权限模型:生产环境建议用 IAM 子账号 + 委托授权,不要在代码里硬编码 AK/SK;
- 路径规范:训练代码中用相对路径或参数传入路径,不要写死
/home/ma-user/...之外的绝对路径。
三、数据准备与标注
ModelArts 的数据管理支持图像分类、目标检测、文本分类、表格等多种数据集类型,也支持智能标注和团队标注。
实战中的经验之谈:
- 先小后大:先标注几百条样本跑通训练,再扩大到全量,避免"标完才发现标签体系错了";
- 版本管理:数据集修改后发布新版本,训练作业引用固定版本,保证实验可复现;
- 标注质量抽检:抽 5%~10% 做交叉复核,比盲目增加数据量更有效;
- 隐私数据:涉及个人信息的数据先脱敏,再上传云端。
四、Notebook:交互式开发环境
创建 Notebook 实例时,核心是选对规格和镜像:
- 规格:CPU 适合数据清洗与调试;GPU/NPU 适合训练。调试阶段用小规格,确认真实训练再换大规格,能显著省钱;
- 镜像:官方预置了 MindSpore、PyTorch 等镜像,已内置 torch_npu、CANN 等依赖,能避免大量环境问题;
- 存储:可以挂载 OBS 目录,但频繁小文件读写建议用实例的本地盘或云硬盘;
- 自动停止:务必配置空闲自动停止,这是最常见的账单"刺客"。
五、从 Notebook 到训练作业
当脚本稳定后,就可以固化为训练作业。一个可复用的入口脚本大致长这样:
import argparse
import os
import torch
def main():
parser = argparse.ArgumentParser()
# 路径由平台或启动参数传入,避免写死
parser.add_argument("--data_url", type=str, required=True)
parser.add_argument("--train_url", type=str, required=True)
parser.add_argument("--epochs", type=int, default=10)
parser.add_argument("--batch_size", type=int, default=32)
args = parser.parse_args()
device = torch.device("npu:0" if torch.npu.is_available() else "cpu")
model = build_model().to(device)
# ... 训练循环 ...
ckpt_path = os.path.join(args.train_url, "model.pt")
torch.save(model.state_dict(), ckpt_path)
print(f"checkpoint saved to {ckpt_path}")
if __name__ == "__main__":
main()
提交作业时需要关注的关键参数:
| 参数 | 说明 | 常见坑 |
|---|---|---|
| 代码目录 | 训练代码所在 OBS 路径 | 依赖文件漏传、目录层级多套一层 |
| 启动文件 | 入口脚本,如 train.py |
相对导入在作业环境失效 |
| 输入/输出 | 数据与产物路径 | 输出目录未挂载导致结果丢失 |
| 规格与节点数 | 单卡/多卡/多机 | 代码未做分布式适配就选多卡 |
| 超参 | 通过命令行注入 | 默认值与代码不一致 |
关于分布式训练,一句话总结:单卡调通之前不要碰多卡。多机多卡涉及 HCCL 通信、数据分片、日志汇总,问题定位成本会成倍增加。
六、模型管理:把产物变成"模型"
训练作业产出 checkpoint 后,需要在模型管理中登记为模型,才能进入部署环节。两种常见来源:
- 从训练作业导入:平台自动关联作业产物,适合常规流程;
- 从 OBS 导入:适合外部训练(如线下 GPU 集群)产出的模型。
一个可部署的自定义模型包,通常包含三部分:
model/
├── config.json # 模型元信息与运行时配置
├── customize_service.py # 自定义推理代码
└── model.pt # 权重或序列化模型
config.json 的字段在不同框架下略有差异,最小示例:
{
"model_algorithm": "image_classification",
"model_type": "pytorch",
"runtime": "python3.9"
}
字段规范请以 ModelArts 官方"模型包规范"文档为准,不同框架(PyTorch / TensorFlow / MindSpore)模板不同。
推理代码的核心是三个钩子:初始化、预处理、推理。骨架如下:
from model_service.pytorch_model_service import PTServingBaseService
import torch
class MyService(PTServingBaseService):
def __init__(self, model_name, model_path):
super().__init__(model_name, model_path)
self.device = torch.device("cpu")
if hasattr(torch, "npu") and torch.npu.is_available():
self.device = torch.device("npu:0")
self.model = torch.load(model_path, map_location=self.device)
self.model.eval()
def _preprocess(self, data):
# 输入反序列化、归一化、resize、转 Tensor
...
def _inference(self, data):
with torch.no_grad():
return self.model(data)
def _postprocess(self, data):
# 转成业务需要的 JSON 结构
...
这段代码只是示意结构,实际项目中还要处理输入格式校验、批量请求、异常兜底。
七、部署上线:在线、批量与边缘
| 部署形态 | 适用场景 | 关键配置 |
|---|---|---|
| 在线服务 | 实时 API 调用 | 规格、实例数、自动扩缩容、灰度升级 |
| 批量服务 | 离线打分、大批量推理 | 输入/输出 OBS 路径 |
| 边缘服务 | 工厂、门店等本地推理 | 边缘节点与模型下发 |
在线服务的几个实战建议:
- 先压测再扩缩容:用固定并发跑出单实例 QPS 与时延曲线,再设置扩缩容阈值;
- 版本灰度:新模型先切小流量,观察错误率与耗时,再全量;
- 冷启动:大模型服务启动慢,扩缩容策略要留出预热时间;
- 鉴权:生产调用建议走 APP 认证或 API 网关,不要把 AK/SK 分发给前端。
八、监控与成本
上线之后,关注两类事情:
稳定性:在应用运维管理(AOM)中观察 QPS、P99 时延、错误率、实例 CPU/内存/NPU 利用率。推理服务的典型故障不是"挂了",而是"变慢了"——多数与实例规格不足或模型版本回退有关。
成本:几个立竿见影的动作:
- Notebook 配置空闲自动停止;
- 训练作业优先用"按需"做实验,稳定后考虑包周期;
- 推理服务设置最小/最大实例数,避免低峰期空转;
- 定期清理 OBS 中的临时 checkpoint,尤其是大模型的分片权重。
九、一条最小可行流水线
把上面所有环节串起来,一个新项目的推荐节奏是:
- 用 Notebook + 小样本数据跑通训练脚本;
- 固化为训练作业,产出 checkpoint 并登记模型;
- 用自定义推理代码部署一个单实例在线服务;
- 压测、调扩缩容、接监控;
- 再回头做数据扩充与模型迭代。
- 点赞
- 收藏
- 关注作者
评论(0)