ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ModelArts企业级AI工程实践:从数据治理到模型服务化全链路

ModelArts企业级AI工程实践:从数据治理到模型服务化全链路 1. 这不是“点几下就能跑通”的玩具平台而是企业级AI工程落地的真实切口我第一次在ModelArts上跑通ResNet50训练任务时花了整整三天——不是因为不会调参而是卡在了数据路径权限配置错误导致的Dataset加载超时上。当时控制台只报了一行模糊的Failed to list objects日志里连具体的OBS桶名都没打出来。后来翻遍华为云文档才明白ModelArts的训练环境默认不继承用户主账号的OBS读写权限必须显式绑定策略而那个策略模板里藏着一个极易被忽略的细节——它要求OBS路径必须以/结尾否则权限校验会静默失败。这个坑我在三个不同客户的项目里都见过包括一家做工业质检的上市公司他们最初把模型训练周期从两周拖到了三周就因为这个斜杠。这不是个例。ModelArts常被误读为“华为版Notebook”但它的底层设计逻辑完全不同它本质是一个面向MLOps全链路的云原生AI平台训练只是其中一环背后是完整的资源调度、镜像管理、版本追踪和模型服务编排体系。你用它训一个YOLOv5和用它部署一个支持千QPS并发的OCR服务走的是完全不同的技术路径。前者可能只需要上传数据集点几下启动后者则必须理解modelarts://协议如何与容器网络打通、为什么inference.py里的app.route(/predict)不能直接写业务逻辑、以及config.json里inputs字段的shape定义为何必须与TensorRT引擎的输入tensor严格对齐。关键词里反复出现的“模型训练”和“模型部署”在ModelArts语境下从来不是割裂的两个动作。训练产出的.pth或.pb文件只是中间产物真正交付给业务系统的是经过服务化封装、资源隔离、健康探针注入、自动扩缩容配置的完整服务实例。这解释了为什么热词里同时高频出现roberta中文预训练模型和本地部署ai模型——前者是训练侧的典型输入后者是部署侧的终极目标而ModelArts的价值恰恰在于把这两端用一套统一的元数据和生命周期管理机制串起来。比如你用Paddle训练的模型导出为inference.json它在ModelArts里会被自动识别为Paddle Serving格式但若想转成轻量级的.nb用于边缘设备就必须在训练阶段就启用paddle_lite_opt工具链并在ModelArts的“自定义镜像”环节注入Lite编译环境——这个决策点早在训练脚本的第一行import paddle之前就该定下来。所以这篇笔记不叫“手把手教你用ModelArts”因为它不是教你怎么点按钮。它是记录我过去两年在六个真实项目中如何把ModelArts从一个“能跑模型的云平台”变成一个可审计、可回滚、可灰度、可计费的AI生产系统。你会看到为什么我们坚持用OBS而非NAS挂载数据为什么训练作业的spec.resources.limits.memory必须比实际占用高30%为什么部署时宁可多花20分钟手动配置VPC对等连接也不用默认的公网访问以及当客户突然要求把模型从GPU实例迁移到Ascend 910B时哪些配置项会连锁失效——这些才是ModelArts学习笔记里真正值得记下的东西。2. 数据准备OBS不是网盘而是AI流水线的“中央枢纽”很多人把OBS当成普通网盘用上传数据集→训练时选路径→完事。这在单次实验中可行但在生产环境中这种做法会迅速演变成一场灾难。我参与过一个医疗影像项目初期团队用个人OBS桶存CT扫描图三个月后数据量涨到47TB权限混乱到连数据科学家都分不清自己有没有GetObject权限。更糟的是当需要回溯某次训练所用的数据版本时发现所有文件都是按日期命名没有哈希校验无法确认是否被意外覆盖。最终我们花了两周时间重建数据血缘代价是延误了FDA认证的关键节点。ModelArts的数据管理核心逻辑是OBS桶即数据源OBS路径即数据版本OBS生命周期策略即数据治理规则。这不是概念而是强制约束。当你在ModelArts控制台创建一个“数据集”时它本质上是在OBS上建立了一个带元数据标签的路径快照。例如你创建一个名为chest_xray_v2.1的数据集指向obs://medical-data/chest-xray/train/那么ModelArts会在后台记录该路径下所有对象的ETagMD5哈希和LastModified时间戳。后续任何训练作业引用此数据集平台都会校验这些哈希值确保数据未被篡改——这是训练结果可复现性的物理基础。2.1 OBS桶结构设计拒绝扁平化拥抱领域分层我们团队的标准OBS桶结构长这样obs://my-ai-project/ ├── raw/ # 原始数据只读禁止修改 │ ├── images/ # 原始图像 │ └── annotations/ # 原始标注JSON/XML ├── processed/ # 预处理后数据按任务类型分层 │ ├── classification/ # 分类任务数据 │ │ ├── train/ # 训练集含label.txt │ │ └── val/ # 验证集 │ └── detection/ # 检测任务数据 │ ├── coco/ # COCO格式 │ └── voc/ # VOC格式 ├── models/ # 模型权重与配置 │ ├── checkpoints/ # 训练中的checkpoint │ └── releases/ # 发布版本带version标签 └── logs/ # 训练日志与评估报告关键设计原则有三条raw目录绝对不可写所有数据清洗、增强、格式转换操作必须输出到processed/子目录。我们用ModelArts的“数据处理作业”功能执行这些操作其输出路径强制指定为processed/下的新路径避免污染原始数据。processed目录按任务类型隔离分类、检测、分割的数据结构差异巨大混放会导致数据集注册失败。例如YOLO格式的labels/目录和分类任务的class_name/目录结构冲突ModelArts在解析数据集时会直接报错Invalid dataset structure。models目录区分checkpoints与releasescheckpoints/下存放训练过程中的.pth文件命名规则为{job_id}_{epoch}.pthreleases/下存放经评估验证的正式版本命名规则为v{major}.{minor}.{patch}-{model_name}如v1.2.0-resnet50并附带metadata.json描述精度、FLOPs、推理耗时等指标。提示OBS桶的Region必须与ModelArts所在Region严格一致。曾有客户将华东-上海的OBS桶用于华北-北京的ModelArts训练结果因跨Region数据传输延迟训练作业在DataLoader初始化阶段超时失败。华为云控制台不会主动提示此限制需在创建OBS桶时手动选择匹配Region。2.2 数据集注册元数据比文件本身更重要在ModelArts控制台注册数据集时最关键的不是选择路径而是填写数据集元数据。以一个YOLOv5训练数据集为例必须正确配置以下字段字段值示例说明data_formatYOLO决定ModelArts如何解析labels/目录下的txt文件image_width640影响数据增强时的resize策略必须与训练脚本中imgsz参数一致image_height640同上classes[person, car, dog]生成classes.txt供训练脚本读取顺序必须与label txt中的数字索引严格对应annotation_typebounding_box告知平台这是检测任务触发相应的预处理算子如果classes字段填错顺序比如把[car, person]写成[person, car]模型训练时label映射就会全乱但损失函数仍会正常下降——因为网络在学一个错误的映射关系。这种bug极难排查往往要等到部署后推理结果完全错位才发现。我们现在的标准流程是每次注册新数据集都用ModelArts内置的“数据集预览”功能随机抽样10张图人工核对classes.txt顺序与标注文件中的数字是否匹配。2.3 权限配置最小权限原则下的策略组合OBS权限配置是ModelArts最易踩坑的环节。常见错误是直接给训练作业赋予OBS FullAccess策略这违反安全规范且埋下隐患。正确的做法是组合使用三种策略OBS ReadOnly Access授予训练作业读取raw/和processed/路径的权限。策略JSON片段如下{ Statement: [ { Effect: Allow, Action: [obs:GetObject], Resource: [arn:aws:obs:::my-ai-project/raw/*, arn:aws:obs:::my-ai-project/processed/*] } ], Version: 1.1 }OBS WriteOnly Access for Logs仅允许向logs/目录写入日志。注意Resource必须精确到路径不能写arn:aws:obs:::my-ai-project/logs/*否则会获得删除权限{ Statement: [ { Effect: Allow, Action: [obs:PutObject], Resource: [arn:aws:obs:::my-ai-project/logs/train-job-{job_id}/*] } ], Version: 1.1 }ModelArts Job Execution Role这是最关键的一步。必须在ModelArts控制台的“全局配置”中为训练作业指定一个自定义IAM角色该角色同时附加上述两个OBS策略。如果跳过此步作业将使用默认角色而默认角色通常只有OBS ReadOnly权限导致训练脚本无法写入checkpoint。注意OBS路径权限校验是大小写敏感的。曾有客户将路径写成obs://My-Ai-Project/processed/首字母大写而OBS桶实际名称是my-ai-project全小写结果权限校验始终失败。华为云文档明确要求OBS桶名必须符合DNS命名规范小写字母、数字、短横线但控制台UI并未强制校验需人工确认。3. 模型训练从“跑通”到“可控”的四层进阶在ModelArts上启动一次训练作业点击“创建训练作业”只需30秒。但让这次训练具备可复现性、可监控性、可优化性、可审计性则需要深入理解四个层级的技术细节。这四层不是并列关系而是递进依赖跳过上一层下一层必然失效。3.1 第一层资源规格与镜像选择——别被“自动推荐”带偏ModelArts控制台会根据你选择的框架PyTorch/TensorFlow自动推荐镜像和GPU规格。但这些建议基于通用场景而非你的具体模型。例如训练一个ResNet50 on ImageNet推荐使用p4V100实例但如果你训练的是一个轻量级MobileNetV3p4的显存利用率常年低于30%而p2T4实例成本低40%性能差距不到8%。我们做过实测在相同batch size下T4训练MobileNetV3的吞吐量为128 img/sV100为138 img/s但单位算力成本$ per img/sT4低37%。更关键的是镜像选择。ModelArts提供两类镜像官方镜像如swr.cn-south-1.myhuaweicloud.com/modelarts-pytorch-1.12:cuda11.3-cudnn8.2-py38预装主流框架和CUDA适合快速验证。自定义镜像需自行构建Docker镜像并推送到SWR华为云容器镜像服务适合生产环境。选择依据很简单只要训练脚本依赖非标准库如albumentations1.3.0或torchvision0.15.0就必须用自定义镜像。因为官方镜像的库版本是固定的无法动态升级。曾有一个OCR项目因easyocr依赖新版torchvision的transforms.RandomPerspective而官方镜像只带torchvision0.13.1导致训练时报AttributeError: module torchvision.transforms has no attribute RandomPerspective。解决方案是构建自定义镜像FROM swr.cn-south-1.myhuaweicloud.com/modelarts-pytorch-1.12:cuda11.3-cudnn8.2-py38 RUN pip install --upgrade torchvision0.15.2 RUN pip install easyocr1.7.1构建后推送到SWR再在训练作业中指定镜像URI。提示自定义镜像的ENTRYPOINT必须与ModelArts兼容。官方镜像的入口是/bin/bash -c你的自定义镜像不能覆盖它否则训练脚本无法执行。正确做法是在CMD中指定启动命令而非ENTRYPOINT。3.2 第二层训练脚本编写——ModelArts专属API的隐式契约ModelArts训练作业的启动命令固定为python train.py但train.py内部必须遵循平台约定否则会丢失关键能力。核心约定有三点参数解析必须用argparse且支持--data_url和--train_urlimport argparse parser argparse.ArgumentParser() parser.add_argument(--data_url, requiredTrue, helppath to dataset) parser.add_argument(--train_url, requiredTrue, helppath to output) args parser.parse_args() # ModelArts会自动将OBS路径挂载到容器内 # args.data_url - /cache/dataset (OBS路径映射) # args.train_url - /cache/output (OBS路径映射)如果脚本不接收这两个参数ModelArts无法传递数据路径训练必然失败。模型保存必须写入--train_url指定路径# 错误直接保存到当前目录 torch.save(model.state_dict(), best.pth) # 正确保存到train_url路径 torch.save(model.state_dict(), os.path.join(args.train_url, best.pth))ModelArts会自动将/cache/output下的文件同步回OBS的--train_url路径。如果保存到其他位置模型文件将丢失。日志输出必须重定向到/log目录# ModelArts会监控/log目录下的日志文件 logging.basicConfig( filename/log/train.log, levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s )否则训练日志无法在控制台查看只能通过SSH登录容器排查效率极低。3.3 第三层超参调试——用ModelArts的“超参搜索”功能前先读懂它的局限ModelArts提供“超参搜索”功能支持随机搜索、网格搜索、贝叶斯优化。但它的贝叶斯优化算法基于Hyperopt有一个致命缺陷不支持离散型超参的条件依赖。例如当optimizeradam时momentum参数应被忽略当optimizersgd时momentum才生效。ModelArts的超参搜索无法表达这种if-else逻辑强行配置会导致无效组合被尝试浪费大量GPU时间。我们的解决方案是用Python脚本生成超参组合再调用ModelArts API批量创建作业。例如针对YOLOv5训练我们写了一个generate_configs.pyconfigs [] for lr in [1e-3, 1e-4]: for batch_size in [16, 32]: for optimizer in [adam, sgd]: if optimizer adam: config {lr: lr, batch_size: batch_size, optimizer: adam} else: config {lr: lr, batch_size: batch_size, optimizer: sgd, momentum: 0.937} configs.append(config) # 调用ModelArts SDK创建作业 for i, cfg in enumerate(configs): job create_training_job( namefyolov5-tune-{i}, image_uriswr.../yolov5:latest, hyperparameterscfg, data_urlobs://.../processed/detection/coco/, train_urlobs://.../models/checkpoints/ )这样既能保证超参空间的有效性又能利用ModelArts的并行调度能力。实测表明在同等GPU资源下脚本生成法比平台内置搜索快2.3倍且最优结果精度高0.8%。3.4 第四层训练过程监控——不止看loss曲线更要盯住GPU的“呼吸节奏”ModelArts控制台的“训练作业详情页”提供loss、accuracy等指标图表但这只是表象。真正决定训练质量的是GPU的利用率曲线。我们总结出GPU“健康呼吸”的三个特征显存占用率稳定在70%-85%低于70%说明batch size太小或数据加载瓶颈高于85%则易OOM触发自动重启。GPU利用率sm__inst_executed呈规律脉冲每个step开始时峰值计算中间平缓数据加载结束时回落。若全程平直说明数据加载慢于计算需调大DataLoader的num_workers。PCIe带宽占用率60%过高意味着CPU到GPU的数据传输成为瓶颈需检查pin_memoryTrue是否启用。这些指标在ModelArts控制台的“资源监控”页可查但默认不显示PCIe带宽。需在训练作业的“高级设置”中勾选“启用PCIe监控”。我们曾遇到一个NLP项目BERT微调时loss震荡剧烈表面看是学习率问题实则PCIe带宽长期95%数据传输卡顿导致梯度更新不同步。启用pin_memory并增加num_workers8后PCIe占用降至42%loss曲线立刻平滑。经验训练作业的spec.resources.limits.memory必须比实际显存占用高30%。例如V100显存32GB若模型数据占24GBlimits.memory应设为32GB。因为ModelArts容器运行时自身需消耗约2-3GB内存若设置过低容器会因OOM被Killed且错误日志只显示Exit Code 137无具体原因。4. 模型部署从“能跑”到“能扛”的七道关卡在ModelArts上部署一个模型点击“部署为在线服务”只需一分钟。但让这个服务在生产环境中稳定支撑1000 QPS、毫秒级响应、自动故障转移、按需弹性伸缩则需要穿越七道技术关卡。每一道关卡都对应一个可能让服务在凌晨三点崩溃的致命细节。4.1 关卡一模型格式转换——不是“导出”而是“重构”ModelArts支持多种模型格式.pth,.pb,.onnx,.mindir但部署时并非所有格式都等效。关键区别在于ONNX是中间表示MindIR是昇腾专用而ModelArts的在线服务引擎基于TensorRT对ONNX有严格的算子兼容性要求。以YOLOv5为例官方导出的ONNX文件包含NonMaxSuppression算子但TensorRT 8.2不支持该算子。直接部署会报错Unsupported ONNX operator: NonMaxSuppression。解决方案是修改导出脚本用torchvision.ops.nms替代原生NMS并在ONNX导出时禁用opset_version12改用11# yolov5/export.py 修改 def export_onnx(model, img, file, opset11): torch.onnx.export( model, img, file, opset_versionopset, # 降级到11 do_constant_foldingTrue, input_names[images], output_names[output], dynamic_axes{images: {0: batch, 2: height, 3: width}} )更彻底的做法是用ModelArts的“模型转换”功能将ONNX转为TensorRT引擎.engine文件。这需要在部署前指定GPU型号如Tesla V100因为引擎是硬件绑定的。转换后的.engine文件部署速度提升40%且规避了所有ONNX算子兼容性问题。4.2 关卡二服务配置——config.json里的魔鬼细节ModelArts在线服务的config.json文件远不止定义输入输出那么简单。以下是生产环境必须配置的七个字段{ model: yolov5s.engine, inputs: [ { name: input_1, shape: [1, 3, 640, 640], // 必须与TensorRT引擎输入tensor shape完全一致 dtype: float32 } ], outputs: [ { name: output_0, shape: [1, 25200, 85], // YOLOv5输出[batch, anchors, (x,y,w,h,obj,cls...)] dtype: float32 } ], preprocess: preprocess.py, // 自定义预处理脚本路径 postprocess: postprocess.py, // 自定义后处理脚本路径 concurrency: 4, // 每个实例的并发请求数影响CPU/GPU资源分配 timeout: 60, // 请求超时秒数必须大于最长推理耗时 health_check: { path: /healthz, // 健康检查端点 port: 8080 } }最易错的是shape字段。如果训练时用imgsz640但config.json里写成[1,3,416,416]服务启动时会报Input tensor shape mismatch且错误日志不提示具体哪一维不匹配。我们现在的标准流程是在训练完成后用trtexec --onnxmodel.onnx --verbose命令打印引擎的输入输出shape再复制到config.json。4.3 关卡三预处理与后处理——业务逻辑的安全部署区preprocess.py和postprocess.py是ModelArts服务的安全边界。所有业务逻辑如图像解码、归一化、NMS、坐标变换必须放在这两个脚本里绝不能写在inference.py的predict函数中。原因有二inference.py是服务框架代码修改它可能导致服务启动失败预/后处理脚本可独立测试便于单元验证。一个典型的preprocess.pyimport numpy as np from PIL import Image import io def preprocess(request_body): # request_body是base64编码的图片字节流 image_bytes io.BytesIO(base64.b64decode(request_body)) img Image.open(image_bytes).convert(RGB) img img.resize((640, 640)) # 与config.json shape一致 img_array np.array(img) / 255.0 # 归一化 img_array np.transpose(img_array, (2, 0, 1)) # HWC-CHW return img_array.astype(np.float32)[np.newaxis, ...] # 添加batch维度postprocess.py则负责将TensorRT输出的[1,25200,85]张量解析为标准JSON格式的检测框def postprocess(inference_result): # inference_result是numpy array boxes inference_result[0] # 取第一个输出 # 执行NMS此处用OpenCV的cv2.dnn.NMSBoxes # 返回[{x1,y1,x2,y2,score,class}, ...] return detections注意preprocess.py和postprocess.py必须放在与config.json同级的目录下且文件名严格匹配config.json中指定的路径。ModelArts不会报错但服务会返回500 Internal Error日志显示ModuleNotFoundError: No module named preprocess。4.4 关卡四网络与安全——VPC对等连接的必要性ModelArts在线服务默认提供公网访问地址https://xxx.modelarts.cn-north-1.myhuaweicloud.com但生产环境严禁直接使用公网地址。原因有三公网带宽有限突发流量易拥塞缺乏细粒度访问控制任何知道URL的人都能调用无法与企业内网系统如ERP、MES直连需额外NAT网关。正确方案是配置VPC对等连接将ModelArts服务所在的VPC华为云自动创建与客户业务系统所在的VPC打通。配置步骤在ModelArts控制台进入“在线服务” → “服务配置” → “网络设置”选择“私有网络访问”指定客户VPC ID和子网在客户VPC控制台创建对等连接接受ModelArts VPC的请求在双方VPC的路由表中添加对方VPC网段的路由条目如192.168.0.0/16。打通后业务系统调用服务的URL变为内网地址http://192.168.10.100:8080/predict。实测表明内网调用延迟稳定在15ms以内而公网调用波动在50-200ms且偶发超时。4.5 关卡五弹性伸缩——基于QPS而非CPU的扩缩容策略ModelArts支持基于CPU/内存使用率的自动扩缩容但这对AI服务是灾难性的。因为GPU利用率sm__inst_executed与QPS并非线性关系当QPS从100升到200时GPU利用率可能从60%升到85%但从200升到300时利用率可能卡在95%此时增加实例才能提升吞吐。因此我们必须禁用基于资源的扩缩容改用基于QPS的指标。操作路径在在线服务详情页点击“编辑配置” → “弹性伸缩”关闭“基于CPU使用率”和“基于内存使用率”开启“基于请求QPS”设置阈值最小实例数2保障高可用最大实例数10防止单点故障扩容阈值QPS 150单实例承载上限缩容阈值QPS 80留出缓冲提示QPS指标采集有1分钟延迟。为避免瞬时流量尖峰导致频繁扩缩我们在业务侧加了令牌桶限流如Redis Lua实现确保流入ModelArts的请求平滑。4.6 关卡六服务治理——健康检查与熔断的双重保险ModelArts的健康检查/healthz默认只检查服务进程是否存活但AI服务真正的健康状态是模型能否正常推理。因此我们必须重写健康检查逻辑# health_check.py import requests import json def health_check(): try: # 发送一个轻量级测试请求 resp requests.post( http://localhost:8080/predict, json{image: base64_encoded_test_image}, timeout5 ) if resp.status_code 200 and detections in resp.json(): return True except Exception: pass return False并将此脚本路径写入config.json的health_check字段。更进一步我们集成Sentinel实现熔断。当连续5次健康检查失败或QPS错误率5%Sentinel会触发熔断将所有请求返回503 Service Unavailable避免雪崩。熔断恢复后先以10%流量试探逐步放大至100%。4.7 关卡七灰度发布——用蓝绿部署规避“一刀切”风险上线新模型版本时我们绝不直接替换旧服务。而是采用蓝绿部署新建一个同名服务如yolov5-v2配置新模型和新config.json将5%流量导入yolov5-v295%留在yolov5-v1监控新服务的精度、延迟、错误率若24小时无异常逐步将流量提升至100%确认稳定后下线yolov5-v1。ModelArts本身不支持流量比例配置我们通过API网关APIG实现在APIG创建一个统一入口/api/detect后端分别指向yolov5-v1和yolov5-v2的内网地址并配置权重路由。这样业务系统无需修改代码只需调用同一个URL。5. 故障排查那些让运维工程师彻夜难眠的“幽灵错误”在ModelArts上90%的故障不会直接报错而是以诡异现象呈现服务响应变慢、精度骤降、日志消失、实例莫名重启。这些“幽灵错误”往往源于平台特性与AI工作流的深层耦合。以下是六个最典型、最折磨人的案例附带完整的排查链路。5.1 现象训练作业日志突然中断最后一条是“Saving checkpoint...”之后再无输出排查链路登录训练作业容器kubectl exec -it pod-name -n namespace -- /bin/bash查看/log/train.log末尾发现OSError: [Errno 28] No space left on device检查容器磁盘df -h显示/cache分区100%满追溯原因/cache是ModelArts挂载的临时存储大小固定为50GB。而训练脚本在/cache/dataset下解压了未清理的压缩包占用了32GB解决方案在训练脚本开头添加清理逻辑import shutil if os.path.exists(/cache/dataset/archive.zip): os.remove(/cache/dataset/archive.zip)根本原因ModelArts的/cache分区不支持自动扩容且du -sh /cache/*命令在容器内不可用权限限制必须用df -h看整体使用率。5.2 现象在线服务返回504 Gateway Timeout但服务实例CPU/GPU利用率均很低排查链路检查服务配置timeout字段设为30秒查看/log/inference.log发现大量Request timeout after 30s抓包分析用tcpdump捕获服务端口流量发现客户端请求在30秒整时被断开追溯根源客户端SDK设置了read_timeout30而服务端config.json的timeout也设为30两者叠加导致请求在29.9秒时被服务端主动关闭解决方案将config.json的timeout设为60客户端SDK设为65留出5秒缓冲。5.3 现象同一模型在不同Region部署精度相差3.2%排查链路对比两个Region的OBS桶华东-上海桶的processed/目录下val/子目录的class_name/结构与华北-北京桶不一致检查数据集注册信息华东桶注册时classes字段为[cat,dog]华北桶为[dog,cat]验证用相同测试图在两地服务上推理类别ID 0在华东对应cat在华北对应dog根本原因ModelArts数据集元数据不跨Region同步每个Region需独立注册且classes顺序必须人工保证一致。5.4 现象GPU实例部署后nvidia-smi显示GPU显存占用100%但nvidia-smi dmon显示GPU利用率0%排查链路nvidia-smi显示No running processes found但显存未释放执行fuser -v /dev/nvidia*发现/dev/nvidia-uvm被/usr/bin/python3进程占用追查该进程ps aux | grep python3定位到一个残留的训练作业容器
返回列表