yolov8华为昇腾适配实战:从PyTorch权重到om模型全链路
简介这份资源面向希望在华为昇腾平台上部署YOLOv8目标检测模型的算法工程师与开发者提供从PyTorch权重到昇腾OM格式的完整适配方案解决跨平台迁移中模型转换与推理落地的核心问题。压缩包共315个文件约153.25MB以92个Python脚本、41个YAML配置、29份Markdown文档为主辅以ONNX与PT权重、Shell脚本及Dockerfile等覆盖模型构建、数据加载、推理后处理等环节。核心脚本pt2om2.py负责将PT模型转换为昇腾OM格式yolov8_om_infer.py则给出昇腾平台上的推理实现便于读者直接复用或二次开发。目前已有949人学习下载适合具备一定深度学习基础、需要将YOLOv8落地到昇腾硬件的中高级开发者参考可快速掌握模型转换流程与推理代码结构减少环境适配与调试成本。1. 从 PyTorch 权重到昇腾 NPUyolov8 华为昇腾适配到底在做什么手里有一份训练好的 yolov8 权重GPU 服务器上跑得好好的现在要搬到华为昇腾 Atlas 200I DK 或者 Atlas 300I 推理卡上这就是 yolov8 华为昇腾适配要解决的事。它不是把.pt文件拷过去就能跑中间要经过模型导出、算子映射、精度对齐三道关。昇腾走的是 CANN 软件栈推理引擎叫 MindX 或者直接用 ATC 把 ONNX 转成.om离线模型PyTorch 那套 CUDA 算子在这里完全用不上。适合谁看手上有昇腾硬件、需要把检测模型落地产线或边缘盒子的工程师以及正在做信创适配、国产化替代方案评估的团队。读完你能自己走通一条从权重到.om再到推理验证的完整链路知道哪几个参数不改必翻车。2. 昇腾适配的底层逻辑为什么不能直接跑 PyTorch 权重2.1 CANN 软件栈与 CUDA 的根本差异昇腾 NPU 的软件栈叫 CANN全称 Compute Architecture for Neural Networks。它和 CUDA 的定位类似但执行模型完全不同。CUDA 下 PyTorch 的算子直接编译成 GPU 指令而昇腾上模型必须先转成中间表示再由 ATC 工具编译成适配达芬奇架构的离线模型.om。达芬奇架构的核心是 Cube 矩阵计算单元和 Vector 向量计算单元卷积、矩阵乘这类密集计算走 Cube激活、归一化走 Vector。yolov8 的 backbone 里大量 C2f 模块和 SiLU 激活能不能高效映射到这两类单元上直接决定推理速度。PyTorch 的算子生态和 CANN 的算子库不是一一对应的。比如torch.nn.SiLU在昇腾上有对应实现但某些自定义算子或者较新的 PyTorch 版本引入的算子CANN 可能还没覆盖。这就是为什么适配的第一步不是写代码而是查算子支持列表。我一般会先把模型导出成 ONNX用 Netron 看一眼图结构再对照 CANN 版本的算子清单逐个确认。另一个容易忽略的点是数据布局。CUDA 下 NCHW 是默认昇腾的某些算子对 NHWC 更友好ATC 转换时会自动做布局调整但如果 ONNX 里插了不支持的 Transpose 节点转换就会失败或者性能暴跌。2.2 yolov8 结构里哪些部分最容易出问题yolov8 相比前代最大的结构变化是 C2f 模块和解耦检测头。C2f 里有 split、concat、多个 bottleneck 堆叠这些操作在 ONNX 图里会展开成一堆 Slice、Concat、Add 节点。昇腾的图编译器对连续的小算子融合能力有限如果不在导出时做优化.om模型里会残留大量碎片化节点推理时调度开销吃掉大部分收益。检测头部分yolov8 的 DFL 模块涉及 Softmax 和卷积组合这个结构在昇腾上通常能支持但要注意 Softmax 的轴参数。如果导出时 axis 设错精度会直接崩。后处理里的 NMS昇腾提供了nms算子但和 PyTorch 的torchvision.ops.nms在边界条件上可能有细微差异需要做对齐验证。还有一个血泪经验yolov8 的 anchor-free 解码逻辑如果放在模型图里会增加不少算子如果放到后处理用 CPU 做又会影响端到端延迟。常见做法是把解码和 NMS 都塞进.om模型用昇腾的MultiClassNMS算子替代这样整个推理链路都在 NPU 上完成。2.3 适配路线的选型ATC 直转还是 MindX SDK 集成两条路。第一条是纯 ATC 路线PyTorch → ONNX → ATC →.om然后用 pyACL 或者 C ACL 接口写推理代码。这条路线控制粒度细适合对性能有极致要求、需要自己管理内存和流的场景。第二条是 MindX SDK 路线用 MindX 提供的 mxVision 或者 mxBase 做高层封装模型还是.om但推理 pipeline 用 SDK 的插件拼装。这条路线开发快适合快速验证和产线部署但灵活性差一些。我一般建议先走 ATC 路线把模型跑通确认精度和性能达标后如果项目需要快速集成到视频流 pipeline再考虑套 MindX SDK。反过来先上 SDK出了问题排查起来层级太深容易卡住。3. 动手做从 yolov8 权重到昇腾 om 模型的完整链路3.1 环境准备与版本对齐昇腾适配最怕版本不对齐。CANN 版本、PyTorch 版本、torch_npu 版本、ONNX opset 版本这四个必须匹配。我踩过的坑是 CANN 7.0 配 PyTorch 2.1 导出的 ONNX opset 17ATC 转换时报了一堆不支持的算子降到 opset 12 才过。所以第一步是确认你的 CANN 版本对应的 torch_npu 版本再决定 ONNX opset。# 查看 CANN 版本 cat /usr/local/Ascend/ascend-toolkit/latest/version.cfg # 确认 torch_npu 是否安装 python -c import torch_npu; print(torch_npu.__version__) # 确认 ATC 工具可用 atc --version这三条命令分别确认 CANN 基础版本、PyTorch 昇腾适配层、模型转换工具是否就绪。如果torch_npu导入报错大概率是 CANN 环境变量没 source执行source /usr/local/Ascend/ascend-toolkit/set_env.sh后再试。ATC 版本要和 CANN 一致混装不同版本的 toolkit 会导致转换出的.om在推理时加载失败。3.2 导出 ONNX参数怎么设才不翻车yolov8 官方仓库的export.py可以直接导出 ONNX但默认参数在昇腾上不一定好用。关键参数有三个opset、simplify、dynamic。opset 建议用 11 或 12太高了 ATC 不认simplifyTrue会调用 onnx-simplifier 做图优化能消掉不少冗余节点dynamic在昇腾上支持有限除非确实需要动态 batch否则设 False。from ultralytics import YOLO model YOLO(yolov8n.pt) model.export( formatonnx, opset12, # 昇腾 ATC 对 opset 11/12 支持最稳 simplifyTrue, # 图简化减少碎片算子 dynamicFalse, # 固定 batch避免动态 shape 转换失败 imgsz640, # 输入尺寸需与后续 ATC 参数一致 halfFalse, # 昇腾上 FP16 由 ATC 控制ONNX 保持 FP32 )导出后得到一个.onnx文件。opset12是经验值CANN 7.x 对 11 和 12 的算子覆盖最全。simplifyTrue会做常量折叠和算子融合减少 ATC 转换时的图规模。dynamicFalse是因为昇腾的动态 shape 支持需要额外配置分档固定 shape 最省事。halfFalse是因为精度转换交给 ATC 的--precision_mode控制ONNX 层保持 FP32 避免精度损失叠加。导出后务必用onnx.checker验证一遍再用 Netron 看输入输出节点名后面 ATC 转换要用到。import onnx onnx_model onnx.load(yolov8n.onnx) onnx.checker.check_model(onnx_model) print(输入:, [i.name for i in onnx_model.graph.input]) print(输出:, [o.name for o in onnx_model.graph.output])这段代码做两件事检查 ONNX 模型结构合法性打印输入输出节点名称。ATC 转换时需要指定--input_shape和--out_nodes节点名写错会直接报错。yolov8 导出的 ONNX 通常输入叫images输出叫output0但不同版本可能有差异以实际打印为准。3.3 ATC 转换命令与关键参数ATC 是昇腾的模型转换命令行工具把 ONNX 编译成.om。这条命令的参数比较多我拆开说。atc --modelyolov8n.onnx \ --framework5 \ --outputyolov8n_ascend \ --input_formatNCHW \ --input_shapeimages:1,3,640,640 \ --out_nodesoutput0:0 \ --soc_versionAscend310B4 \ --precision_modeallow_fp32_to_fp16 \ --logerror--framework5表示输入是 ONNX这是固定值。--output指定输出模型名前缀生成yolov8n_ascend.om。--input_formatNCHW和--input_shape必须和 ONNX 输入一致images:1,3,640,640对应 batch1、3 通道、640×640。--out_nodes指定输出节点格式是节点名:端口号写错会导致模型没有输出。--soc_version是最关键的参数必须和你实际硬件匹配Atlas 200I DK A2 是Ascend310B4Atlas 300I Pro 是Ascend310P3写错了转换能过但推理会挂。--precision_modeallow_fp32_to_fp16允许 FP32 降 FP16 加速如果精度敏感可以改成must_keep_origin_dtype但速度会降。转换成功后终端会打印算子融合信息和最终模型大小。如果报E19999之类的算子不支持错误回去查 ONNX 里对应节点要么换 opset 重导要么在导出时替换掉不支持的算子。3.4 用 ais_bench 做快速精度和性能验证模型转出来了先别急着写推理代码用昇腾自带的ais_bench工具跑一遍确认模型能加载、输出 shape 对、精度没崩。# 生成随机输入数据 python3 -c import numpy as np data np.random.rand(1,3,640,640).astype(np.float32) data.tofile(input.bin) # 跑 ais_bench ais_bench --modelyolov8n_ascend.om \ --inputinput.bin \ --outputresult.bin \ --outputSize1000000 \ --device0第一段生成一个符合输入 shape 的随机 bin 文件。第二段ais_bench加载.om模型喂入数据输出结果到result.bin。--outputSize要设得比实际输出大不然会截断。跑通后看终端打印的推理耗时这是纯 NPU 计算时间不含前后处理。如果这一步就报错说明模型转换有问题不用往下走了。精度验证需要拿真实图片跑一遍 PyTorch 和昇腾两边的输出做对比。我一般会取 10 张验证集图片分别跑.pt和.om算输出的余弦相似度低于 0.99 就要查原因。4. 避坑指南昇腾适配 yolov8 最常见的 5 个翻车点4.1 坑一ATC 转换报算子不支持现象执行 atc 命令后报E19999: Value of attr [xxx] is invalid或者The node [xxx] is not supported。原因ONNX 里存在 CANN 当前版本不支持的算子常见的有Resize的某些插值模式、ScatterND、自定义的SiLU变体。yolov8 的 upsample 层如果用了nearest之外的插值方式很容易触发。解决先用 Netron 定位报错节点确认它的 op_type。如果是 Resize把插值模式改成nearest重新导出如果是其他算子查 CANN 算子清单看有没有替代实现。实在不行就在 PyTorch 导出前把该算子替换成等价的支持算子组合。4.2 坑二模型转换成功但推理输出全零现象.om模型能加载ais_bench也能跑完但输出结果全是 0 或者 NaN。原因大概率是--out_nodes写错了模型实际输出节点和指定不符导致取到了中间层的空数据。另一个可能是--input_shape和 ONNX 不一致数据喂进去后维度对不上计算全乱。解决用 Netron 打开 ONNX 确认输出节点名和端口号重新执行 ATC。同时检查--input_shape的 batch、通道、高、宽是否和 ONNX 输入完全一致。如果 ONNX 是动态 shape先固定成静态再转。4.3 坑三精度掉点严重mAP 掉超过 5 个点现象昇腾上跑出来的检测框位置偏移大或者置信度普遍偏低mAP 相比 GPU 掉 5 个点以上。原因--precision_mode设成了allow_fp32_to_fp16某些对精度敏感的层比如 DFL 里的 Softmax降 FP16 后误差累积。另一个可能是后处理 NMS 的阈值和 PyTorch 不一致。解决先把--precision_mode改成must_keep_origin_dtype跑一遍如果精度恢复说明是 FP16 的问题可以用--precision_modeallow_mix_precision配合--modify_mixlist指定哪些层保持 FP32。如果是 NMS 问题对齐两边的iou_threshold和score_threshold昇腾 NMS 算子的边界处理和 torchvision 有细微差异建议用同一组输入做逐框对比。4.4 坑四多 batch 推理时性能不升反降现象batch1 时延迟 20ms改成 batch4 后延迟变成 100ms吞吐量没提升。原因ATC 转换时没有开启动态 batch 或者分档配置模型实际还是按 batch1 编译的多出来的数据走了多次推理。另一个可能是内存拷贝成了瓶颈输入数据在 Host 和 Device 之间来回搬。解决如果确实需要多 batch在 ATC 转换时用--dynamic_batch_size指定分档比如--dynamic_batch_size1,4,8。同时检查推理代码里是不是每次推理都重新申请了 Device 内存应该复用内存池。昇腾的 ACL 接口里aclrtMalloc和aclrtFree要配对且尽量少调用。4.5 坑五模型在开发板能跑换到推理卡就挂现象Atlas 200I DK 上跑通的.om放到 Atlas 300I 推理卡上加载失败报model version mismatch或者直接段错误。原因ATC 转换时的--soc_version指定的是开发板的芯片型号不同昇腾硬件的指令集和内存布局有差异.om模型不跨硬件通用。解决针对目标硬件重新执行 ATC 转换--soc_version改成推理卡对应的型号。Atlas 300I Pro 是Ascend310P3Atlas 800 训练服务器是Ascend910。如果项目要同时支持多种硬件就维护多份.om推理时按设备类型加载对应模型。5. 进阶技巧用混合精度和算子调优把 yolov8 在昇腾上压榨到极致模型跑通只是及格线真正落地要看延迟和吞吐。这一章说两个我常用的调优手段。第一个是混合精度配置。allow_fp32_to_fp16一刀切会掉精度must_keep_origin_dtype又太慢。折中方案是用allow_mix_precision配合自定义混合精度列表。具体做法是在 ATC 命令里加--modify_mixlistoplist.json这个 JSON 文件里指定哪些算子保持 FP32、哪些走 FP16。yolov8 里我一般会把检测头最后的卷积和 DFL 的 Softmax 保持 FP32backbone 的卷积全部走 FP16。{ Conv: allow_fp16, Softmax: must_fp32, Sigmoid: allow_fp16, Mul: allow_fp16, Add: allow_fp16 }这个列表不是固定的不同 CANN 版本支持的算子名可能有差异。生成方式是用 ATC 的--precision_modeallow_mix_precision先跑一遍它会输出一个默认的 mixlist 文件在这个基础上改。改完重新转模型用验证集测 mAP通常能在精度损失 1 个点以内换来 30% 以上的速度提升。第二个是算子融合调优。ATC 转换日志里会打印融合后的算子数量如果发现融合率低可以在命令里加--fusion_switch_file指定融合规则文件强制开启某些融合模式。另外把后处理 NMS 塞进模型图里用昇腾的MultiClassNMS算子比在 CPU 上做 NMS 再拼回结果要快得多尤其在高分辨率输入下差距明显。验证调优效果不能只看单次推理耗时要用ais_bench的--loop参数跑 100 次取平均同时用npu-smi info看 NPU 利用率和内存占用。如果利用率低于 60%说明瓶颈在数据搬运或者后处理不在 NPU 计算本身这时候优化方向要转到 pipeline 并行上。我自己的习惯是每改一个参数就存一版.om和对应的精度、性能数据用表格记下来。昇腾适配的变量太多不记录的话回头根本不知道哪版是能用的。配置项精度 mAP单帧延迟备注FP32 全保持0.51245ms基线全 FP160.48722ms掉点明显混合精度0.50828ms推荐混合精度NMS入图0.50824ms最优这张表是我在 Atlas 300I Pro 上跑 yolov8n、640×640 输入的实际记录不同硬件和 CANN 版本会有差异但趋势一致。混合精度加 NMS 入图是性价比最高的组合精度只掉 0.4 个点延迟降了将近一半。最后说一个我踩过的坑调优过程中不要同时改多个参数。有一次我同时改了精度模式和融合规则结果精度崩了排查了一天才发现是融合规则把某个关键算子融错了。后来我就定了个规矩每次只动一个变量改完必须跑完整验证集确认没问题再动下一个。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

前端虚拟滚动技术优化大型树形表格性能实践

前端虚拟滚动技术优化大型树形表格性能实践

1. 项目背景与问题分析 作为一名长期奋战在前端性能优化一线的开发者,我最近接手了一个极具挑战性的需求:在一个生产管理系统中,需要展示包含数千条工艺数据的树形表格,每个工艺节点下又嵌套着数十项子产品数据。更棘手的是&#…

2026/10/14 9:41:22 阅读更多 →
3D迷宫漫游实验:手写矩阵、第一人称相机与碰撞检测实战

3D迷宫漫游实验:手写矩阵、第一人称相机与碰撞检测实战

简介:这份资源是山东大学计算机图形学实验二的完整实现,面向正在学习OpenGL与三维图形编程的高校学生及自学者,解决从零搭建可交互3D迷宫漫游场景的实践难题。压缩包共246个文件,约25.92MB,包含cpp与h源码、obj与md2替…

2026/10/14 9:41:22 阅读更多 →
SwiftUI与Agent结合:智能体技能封装实战指南

SwiftUI与Agent结合:智能体技能封装实战指南

1. 这个标题到底在说什么 第一次看到“SwiftUI-Agent-Skill”这个组合词,我的直觉是:这大概率是一个把苹果生态的声明式 UI 框架和智能体(Agent)能力做结合的项目,而且“Skill”这个词暗示它可能不是一个大而全的框架&…

2026/10/14 9:41:22 阅读更多 →

最新新闻

Linux下Modbus TCP服务端实战:寄存器规划与数据采集指南

Linux下Modbus TCP服务端实战:寄存器规划与数据采集指南

简介:基于Linux平台的TCPModbus服务端实现,面向工业自动化开发人员、嵌入式工程师及Modbus协议学习者,用于解决各类工业设备通过TCP/IP网络与上位机或PLC进行数据通信的需求。服务端覆盖输入寄存器(0x04)、离散输入&am…

2026/10/14 16:24:36 阅读更多 →
Linux 下用 nvm 升级 Node.js 到指定版本:安装、切换与回滚全指南

Linux 下用 nvm 升级 Node.js 到指定版本:安装、切换与回滚全指南

前阵子帮人处理一台 Linux 服务器,对方想跑一个依赖 Node.js 新特性的工具,结果node -v打出来还是 18.x。按老思路,要么用系统包管理器升级,要么去官网下二进制包直接替换,可那是台带着线上服务的机器,谁也…

2026/10/14 16:24:36 阅读更多 →
短视频虚假宣传判定标准更新,带货博主内容合规要点梳理

短视频虚假宣传判定标准更新,带货博主内容合规要点梳理

短视频带货是直播电商自媒体很常用的变现方式,创作者靠着短视频介绍商品,引导消费者下单购买。现在带货类的内容数量越来越多,平台更新了短视频虚假宣传的判定标准,不少带货博主都在翻看这份新规,不想让自己的账号受到…

2026/10/14 16:24:36 阅读更多 →
光芯片太火,连卖百货的都坐不住了

光芯片太火,连卖百货的都坐不住了

导语:东百集团准备拿出3.16亿元跨界“追光”。一家做了多年百货、购物中心和仓储物流生意的上市公司,突然决定去买光芯片。10月11日晚,东百集团披露,公司全资子公司东百创智拟以3.16亿元,收购杭州快灵光电科技有限公司…

2026/10/14 16:24:36 阅读更多 →
影策3D导演台教程:生成前先摆场走位运镜,短剧镜头规划神器

影策3D导演台教程:生成前先摆场走位运镜,短剧镜头规划神器

人工智能AI 应用媒体生成音视频工作流自动化后端前端 【免费下载链接】open-ai-canvas 【影策】面向 AI 影视创作的开源无限画布工作台,集成多模态生成、分镜编排、素材管理与 Agent 工作流。 项目地址: https://gitcode.com/gh_mirrors/op/open-ai-canv…

2026/10/14 16:24:36 阅读更多 →
[特殊字符] AI学会绕锁!小白程序员必看:网络安全新挑战与收藏指南

[特殊字符] AI学会绕锁!小白程序员必看:网络安全新挑战与收藏指南

🔒 AI学会绕锁!小白程序员必看:网络安全新挑战与收藏指南 本文探讨了AI模型Claude Haiku 4.5在测试中绕过禁令,提交虚假警情至费城警方的案例。文章分析了模型未违规的原因,即禁令中缺少“不许提交表单”的规定。Anth…

2026/10/14 16:23:35 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →