从本地到云端:华为云ModelArts全流程训练与部署实践

发布时间:2026/10/22 6:28:23
从本地到云端:华为云ModelArts全流程训练与部署实践
1. 从一次本地训练翻车说起我为什么转到ModelArts先交代一下背景。我之前一直在本地用笔记本跑一些小模型数据量小的时候还凑合直到有一次要训练一个图像分类模型数据集大概几千张图。笔记本的显卡转得跟风扇赛跑一样一个 epoch 跑二十分钟从头到尾调了两天参数实在顶不住。身边做算法的朋友跟我提过几次“云上训练”其中被提得最多的就是华为云 ModelArts。当时我对它的理解很模糊以为就是一个“远程跑代码的服务器”后来真用下来才发现它比我想象的要完整得多——尤其是把训练和部署串成一条线这件事。这篇学习笔记我尽量按照我实际操作的顺序来写从注册账号开始到数据准备、训练作业、模型部署最后把在线服务调通全程基于华为云 ModelArts 完成。文中会穿插不少我第一次使用时踩过的坑也有一些选型思路尽量让第一次接触的朋友能少走一点弯路。ModelArts 是一个面向 AI 开发者的托管式平台你可以理解为“AI 开发全流程的一站式流水线”。它把数据准备、模型训练、模型部署这三个原本分散在好几套系统里的事情集中到同一个平台上操作。对我这种不想自己搭 GPU 服务器、不想折腾 Docker 镜像、又不想写后端推理接口的人来说它的价值是很直接的。这篇笔记适合谁看我觉得是两类人。一类是刚接触机器学习、想找一个能快速验证想法的环境另一类是已经在本地跑过一些代码但被环境和算力问题反复折磨想了解云上流程怎么走通的人。如果你是这些情况中的一种下面这些内容应该对你有用。2. 先搞明白 ModelArts 到底帮我省了哪些事2.1 它和我自己租台 GPU 服务器到底有什么区别其实一开始我纠结过一个问题我不就是用 GPU 跑代码吗为什么不直接租一台带显卡的云服务器自己装环境后来想明白ModelArts 和云服务器的区别不只是一个“有没有预装环境”的区别。自己租服务器的路线是这样的买服务器、装驱动、装 CUDA、装深度学习框架、装各种依赖库然后写脚本把数据传上去跑完以后把模型下载下来接着还得自己想办法把模型包装成 HTTP 接口部署成服务。这条路不是走不通而是每一步都在消耗你的注意力。尤其是环境安装一次版本不兼容就能耗掉一晚上的时间。而 ModelArts 把这些做了抽象你不需要关心底层机器长什么样只需要关注三件事数据准备好了吗、训练脚本正确吗、模型怎么上线。它把“训练环境”和“推理环境”都封装成了可复用的服务我只要选择算法、指定数据路径、配置资源它会在后端的资源池里调度一台机器来跑跑完以后结果直接存到对象存储里。2.2 完整的链路价值不只是训练而是“训完就能部署”我个人体会最深的一点是ModelArts 不只是把“训练”这一个环节托管了它把全流程都串起来了。数据在对象存储里训练任务直接读训练输出自动写回对象存储然后可以在平台上一键把这个输出注册成 AI 应用最后部署成 API 服务在线调用。这种串联带来的好处是你在每一步之间不用再做额外的搬运工作。我第一次走通全流程时的体感是原来从“一个数据集”到“一个可以调用的接口”中间竟然可以没有断点。这对学习阶段的帮助很大因为减少了很多无意义的工程调试把精力留给了模型本身。2.3 我给自己规划的思路先跑通再深入第一次接触 ModelArts 的时候我担心它会不会很复杂于是给自己定了一个最小目标用一个小型数据集跑通“数据上传 → 训练 → 部署 → 调用”这条链路。只要这条链路通了后面再换自己的数据和算法就只是替换中间环节的问题。这个思路对我自己非常有效。后续所有章节里我都会按照这个学习路径来展开。如果你也想快速建立对 ModelArts 的整体认知建议你先别惦记那些高级功能先让它把一条最简单的链路跑起来。3. 开通账号与环境准备最容易卡住的第一关3.1 账号开通与实名认证开始之前需要有一个华为云账号这一步按官网提示操作就可以。我提醒一句实名认证最好提前做完因为创建部分资源、使用某些付费服务时都会校验认证状态。如果之前没有注册过整个过程大概十来分钟。登录控制台以后搜索“ModelArts”进入服务页面。首次使用需要点击“开通”平台会自动在你的账号下创建一个独立的资源空间。这个“开通”操作是一次性的后面使用就不需要再重复了。3.2 创建 OBS 桶先搞清楚它和 ModelArts 的关系ModelArts 本身不保存你的原始数据和模型文件它需要从对象存储服务 OBS 里读取数据训练完成后再把输出写到 OBS。所以 OBS 桶是整条流程的“底座”相当于你的数据仓库。我创建 OBS 桶时第一次踩坑就是在区域选择上。OBS 桶所在的区域必须和 ModelArts 所在的区域保持一致。不然后面创建训练作业时你会在数据路径里找不到自己的桶或者明明上传了数据训练任务却说文件不存在实际上就是区域不通。我当时没注意随便选了个区域结果后面又把数据重新传了一遍很浪费时间。提示区域这个概念一定要重视。控制台左上角有区域切换创建 OBS 桶和后续使用 ModelArts 时务必保持同一个区域。3.3 桶的权限配置学习阶段用私有桶就够了创建桶的时候有一个“桶权限”选项默认就是私有桶。对个人学习来说私有权限完全够用。有些朋友会把权限设置成公共读方便下载数据但也会带来安全问题。学习阶段不用折腾权限保持默认即可。有一点需要说明ModelArts 访问你的 OBS 桶是靠“委托”机制来完成的。创建训练作业时平台会提示你授权一个委托赋予 ModelArts 访问 OBS 的权限。按引导创建一个新的委托即可比如选择“自动创建”它会自动配置好最小必要权限不需要手动折腾策略。3.4 数据上传控制台拖拽还是命令行工具数据量小的时候直接用 OBS 控制台上传就行网页端支持拖拽上传几百张图片、几十 MB 的规模完全没问题。可我第一次遇到的情况是数据集分了十几个子目录单张图片虽然不大但整体有差不多两个 GB。网页上传这种东西会非常吃力中途断掉还得重新来。这时候最好用obsutil命令行工具支持批量上传、断点续传速度也要稳得多。# 配置 obsutil 并上传一个文件夹到桶 ./obsutil config -i你的AccessKey -k你的SecretKey -e你的Endpoint # 递归上传本地 data 目录 ./obsutil cp data obs://your-bucket-name/data -rAccessKey 和 SecretKey 在“我的凭证”里可以创建建议只授权需要的权限。把数据传到 OBS 之后可以在控制台里看到桶对象列表中已经出现完整的数据目录。3.5 费用问题学习阶段的省钱方案这里必须说一下费用因为这也是我第一次使用时比较担心的方面。ModelArts 多数能力都是按量计费的比如训练作业按运行时长计费在线服务按部署时长计费。学习阶段只要不用的时候把资源释放掉费用通常可控。我自己建议一个原则没在跑训练、没有在调试服务的时候就把训练作业停掉把在线服务删除。不要觉得“挂着也没事”在线服务是按小时扣费的挂一天就是一天的钱。后面第五节我会专门讲怎么控制这部分成本。4. 数据准备一份规范的数据集能省下大量调错时间4.1 数据集从哪来先用现成的别自己折腾我建议第一次学习时不要一上来就用自己的业务数据。原因很简单业务数据往往需要清洗、标注、格式整理这些工作会和平台本身的流程问题混在一起出了问题很难判断是数据的问题还是平台使用的问题。ModelArts 的 AI Gallery 里有不少现成的数据集找一个小规模的图像分类数据集来练手。我第一次用的是花卉分类数据大概十几个类别几千张图片数据已经做好了标注下载下来导入 OBS 就能用。先把流程跑通之后再换自己的数据逻辑是一样的。4.2 上传到 OBS 之后的目录结构设计数据集上传到 OBS 之后目录结构会直接影响训练脚本的读取逻辑。这里有一个容易犯的错误想当然地在脚本里写本地路径比如./data/train结果训练作业运行时根本找不到这个目录。在 ModelArts 中训练任务的输入路径是从 OBS 指定的你需要把数据集在桶里的位置映射为训练脚本里的一个参数。比如在创建训练作业时设置一个名为data_url的参数值为obs://your-bucket-name/flower_data。脚本里通过环境变量或 argparse 读取这个参数再去访问数据集。import argparse parser argparse.ArgumentParser() parser.add_argument(--data_url, typestr) parser.add_argument(--train_url, typestr) args parser.parse_args() # 如果平台把 OBS 路径挂载到了本地可以直接用本地路径读取 # 否则需要借助 moxing 把数据拷贝到本地4.3 数据集切分训练集、验证集、测试集最开始我还纠结过数据集的切分逻辑后来发现 ModelArts 的数据管理功能可以直接做切分。在数据集创建界面里可以设置训练集和验证集的比例。我一般按 8:1:1 来切也就是 80% 用于训练10% 用于验证10% 用于测试。如果是使用 AI Gallery 的数据集通常已经内置了切分好的标注信息直接创建数据集即可。这里不需要做太复杂的事情不要为了切分而切分把精力留到后面训练环节。4.4 数据标注先理解平台需要什么样的标注格式图像分类数据集的标注格式很简单每个图片对应一个类别标签。ModelArts 的数据集创建流程中会列出已经识别到的标注信息。如果你用的是自己的数据需要在“数据标注”页面做一些标注操作好在这个平台支持自动标注和人工标注结合效率不低。我第一次用的时候以为标注一定要自己手工一张张做后来发现平台具备自动标注能力可以先跑一轮“自动分组”或“智能标注”再人工修正一部分效率能高不少。注意无论什么类型的数据集最终都要保证“图片文件名”和“标注信息”能对得上。数据管理页面里可以预览多看一眼能避免后面训练时标签错乱。5. 训练作业从预置算法到自定义脚本5.1 第一次训练先用预置算法建立基准线在 ModelArts 里创建训练作业时有两种常见方式使用“预置算法”或者使用“自定义镜像/脚本”。第一次接触的话我强烈建议先用预置算法跑一轮。预置算法相当于平台帮你写好了一套完整的训练代码你只需要指定数据路径和输出路径再设置几个关键参数就行。这个过程能让你快速感受“训练作业”这个抽象概念是怎么运作的也不会因为脚本 bug 给自己增加挫折感。我用预置的图像分类算法跑完一轮之后得到模型的准确率大概在什么水平心里就有个底了。这个底数很重要后续换自定义脚本时可以拿它来对照判断自己写的方法到底有没有问题。5.2 自定义训练脚本三个位置最容易出错等流程跑通之后就可以开始用自己写的脚本了。我自己在自定义脚本阶段踩了不少坑集中在三个地方第一个是依赖库的安装。ModelArts 的预置镜像带了不少常见的库但未必有你需要的那个版本。如果脚本里 import 了一个不存在的包训练作业会在最开始阶段就报错。解决办法是在创建训练作业时加上“安装依赖”的配置把需要的库写到requirements.txt里例如scikit-learn1.2.2 tensorflow2.10.0第二个是数据的读取。上一节说过OBS 的路径和本地路径不一样脚本里不能想当然地写死。ModelArts 的旧一些版本会通过moxing把 OBS 数据拷贝到本地缓存目录再读取本地路径。新版本的训练作业也支持直接访问 OBS但逻辑会略有差异。最简单的做法是把数据路径作为参数传入脚本import moxing as mox # 调用 moxing 把 OBS 数据拷贝到本地 /cache/data mox.file.copy_parallel(args.data_url, /cache/data)第三个是模型输出位置。训练完成后的模型文件必须写到args.train_url对应的路径下。如果脚本里把模型保存到了当前目录训练结束后你在 OBS 里就什么都找不到。# 保存模型到输出路径 mox.file.copy_parallel(/cache/model, args.train_url)5.3 资源选择GPU 还是不选 GPU创建训练作业的时候需要选择资源规格。学习阶段建议选择按量付费的 GPU 规格能明显缩短跑一轮的时间。如果你只是用很小的数据集验证流程CPU 规格也能跑但时间会拉长不少。我个人经验是先选小的比如一个单卡规格用最小的数据集跑通全流程确定脚本没问题后再回到控制台升级规格跑完整数据。没必要一开始就上大配置那纯属烧钱。5.4 日志查看与训练过程诊断训练作业运行的时候我建议养成顺手看日志的习惯。在训练作业详情页可以直接打开日志视图看到实时输出的 stdout 和 stderr。如果你发现日志一直停在那不动不一定是卡死了可能是框架初始化比较慢也可能是输出缓冲导致日志没有实时刷新。一个很实用的技巧在脚本最前面加上环境变量强制标准输出实时刷新。import os os.environ[PYTHONUNBUFFERED] 1这样日志里的print操作就会立即出现在训练日志中定位问题会快很多。我第一次跑训练时日志停留在“加载数据”那个阶段很长时间差点以为死机了后来加了这一行才看到实际是在下载和预处理数据。6. 模型部署把训练结果变成可调用的接口6.1 把模型文件注册成 AI 应用训练完成后模型文件会保存到之前指定的输出路径obs://your-bucket-name/train_output/下。接下来需要在 ModelArts 控制台里直接“创建 AI 应用”把它注册成一个可部署的应用。这里有两种方式如果用预置算法跑出来的模型平台会自动识别模型文件的格式如果是自定义模型通常需要提供一份model目录里面包含模型文件和推理脚本。学习阶段建议先用预置算法生成的模型做部署成功率最高。自定义模型需要额外学习推理代码的编写这部分可以放到第二步再深入。6.2 部署在线服务配置规格与等待启动AI 应用创建成功之后点击“部署-在线服务”进入部署配置页面。这里可以选服务的规格。分类问题不大一个 CPU 实例基本就能支撑测试请求如果要做性能验证再考虑 GPU 实例。部署过程需要等待几分钟。第一次部署时我盯着状态栏等得有点着急其实这个过程是在把模型文件加载到服务环境中是正常的。看到服务状态变为“运行中”就说明已经部署成功了。6.3 调用接口测试一下模型能否正常工作服务部署完成后平台会给你一个 API 地址。拿到地址以后就可以发送请求来测试了。一个最简单的测试方式是直接上传一张图片通过平台的在线测试页面看到预测结果。如果想用代码测试可以这样发起 POST 请求curl -X POST https://your-service-endpoint/v1/infers \ -H Content-Type: application/json \ -H X-Auth-Token: your-token \ -d {image_url: https://example.com/test.jpg}图片如果不在外网可访问的地址也可以直接把图片转为 base64 编码传过去。返回结果一般会包含每个类别的置信度取最大的那个就是推理结果。6.4 部署之后别忘了一件事关闭服务这一步看起来简单但真的很重要。在线服务是按部署时长持续计费的如果你试验完就让服务一直挂着费用会一直在涨。我自己的做法是测试完就把在线服务删除下次需要时再重新部署。重新部署一次也就几分钟但省下的费用是实打实的。提醒所有“按需计费”的资源只有真正在跑的时候才花钱。养成用完即停的习惯是每一位初学者的必修课。7. 几个常见卡的点和我的解决办法7.1 区域不一致导致“找不到数据”这个坑我前面提到过实在值得单独列出来。OBS 桶在上海区域ModelArts 却选在北京区域创建训练作业时无论怎么填数据路径系统都提示找不到对应路径。检查方法也简单看控制台左上角的区域位置保证桶和 ModelArts 一致必要时在两个区域各创建桶但不要跨区域引用数据。7.2 训练脚本一运行就报“No module named xxx”这个问题基本上就是依赖缺失。处理思路是先在本地把训练脚本跑通记录用到的所有第三方库及其版本号再在创建训练作业时把它们写进requirements.txt。如果某个库版本比较特殊建议先在本地验证一下这个版本能正常导入和调用。7.3 训练日志里什么都没有等得心慌如果日志长时间没有任何输出优先检查是否 Python 输出被缓冲。很多初学者都遇到过这种情况不是作业卡死了而是输出还在缓冲区里没刷出来。解决办法就是加环境变量PYTHONUNBUFFERED1脚本里尽早设置os.environ。如果设置之后仍然长时间没有输出再考虑是不是数据读取阶段卡住这时候可以在数据读取代码前后各加一个print来缩小问题范围。7.4 模型部署后调用返回 500 或异常结果部署本身是成功的但调用的结果不对大概率是推理脚本里对输入数据的处理方式不匹配。比如训练时图片做了归一化推理时也要做相同的归一化训练时图片尺寸是 224×224推理时也要统一缩放到相同尺寸。这类前后处理不一致的问题在自定义模型中尤其容易出现。如果使用的是预置算法生成的应用一般不容易遇到这种问题这也是我建议先跑预置算法的原因。8. 学习路线和后续可以深入的方向写到这里我的学习笔记主体已经基本完成了。最后想说一下接下来可以继续深挖的几个方向算是我自己规划的一点点思路。首先是自定义模型部署。我现在跑通的还是预置算法的部署流程接下来打算研究一下如何把自己训练的模型包打包成 ModelArts 需要的 AI 应用格式。这部分需要编写推理脚本和模型配置文件算是整个平台里工程难度相对大的环节但学会了以后应用面会广很多。其次是训练参数调优。云上训练最大的好处是可以并行开多组实验直接对比不同学习率、不同优化器的效果不需要像本地那样一个个排队跑。这个特性用好了调参效率能比本地高一个量级。还有一个值得探索的是自动学习功能。它对不需要深度学习细节的场景很友好。如果你手头有数据但不想写训练代码可以试试自动学习它会自动完成模型训练和调优适合解决“快速拿到一个能用的模型”这类需求。个人体会是ModelArts 学习曲线其实不算陡前提是不要一开始就追求把所有功能都理解透彻而是先让它帮你跑通一个最小的流程。等你亲眼看到数据从 OBS 走到训练作业、再从训练作业变成在线服务的整个过程这整条链路就不再是黑盒了。后面再叠加自己的数据、自己的脚本、自己的模型都会顺理成章很多。