AI芯片软硬件协同设计:从需求拆解到编译器调度的完整链路
很多做AI芯片的朋友都问过我一个问题软硬件协同设计到底有没有一个“标准流程”我前几篇分别聊过量化、编译器和算子的底层优化但在项目里把这些串起来的时候往往会发现真正的瓶颈是“两侧定义接口”的那层功夫。第四篇正好借一个刚结束的参考项目做一次复盘讲讲从需求拆解到驱动代码落地的完整链路里软硬件双方到底是怎么互相“逼”出方案的。先说清楚这篇的服务对象你不是第一次看这个系列已经了解AI芯片的基本构成比如MAC阵列、片上SRAM、DMA和指令集大概是什么样的。你真正想搞明白的是这些模块之间如何确定彼此的分工边界以及为什么某次流片回来性能远远达不到理论值。这篇就用一个智能边缘场景的推理芯片设计过程来带出这些判断逻辑。1. 从真实负载反推硬件规格不能一开始就谈“算力”做AI芯片最容易犯的错误是先用一个TRm接着觉得“算力高就赢了”。实际上AI推理芯片的性能从来不是靠峰值算力撑起来的而是靠“在约束条件下让数据持续流过计算单元”。这个参考项目的目标场景是某类端侧多模态感知应用包含一个约2亿参数的稀疏化视觉模型和一个喂给它的音频流后处理子网。我们把负载拆开看AI推理任务里最有价值的信息不是“这个模型有几十层”而是每层的数据类型、张量形状、复用模式和访存比例。于是先做了一层算子级剖析。最终分析出四大类算子常规卷积、深度可分离卷积、矩阵乘以及大量Elementwise融合操作它们分别占整个模型迭代时间的45%、17%、28%和10%。于是硬件设计的第一条约束就有了不能设计成纯矩阵乘加速器因为矩阵乘只占28%其余需要SIMD化和流水化的支持。于是计算阵列被规划为由16x16的MAC阵列构成的“张量核”中心外加一条独立的SIMD流水线来处理Elementwise和激活操作并在缓存和连接上将“非张量指令”的延迟单独照顾。由此得到的架构基准确立为INT8峰值约16 TOPSMAC阵列最高频率500MHz权重与激活的片上平均复用率大于70%。这些数字不是拍脑袋定的它们全是从模型里每个算子的输入尺寸、通道数和卷积核大小反推出来的。1.1 算力数字的推导过程我们取矩阵乘部分作为例子。假如某层输入是 2048x2048xINT8要做相同维度的矩阵乘MAC次数为 2048x2048x2048次乘加再加上加法一共大约17.2 GFLOPs。若要求整层在1.07毫秒内完成所需算力就是 17.2G / 1.07ms ≈ 16.1 TFLOPs。注意这里已经把乘和加分别计入了FLOPs这也是芯片规格书上常见的INT8 TOPS口径。在设计MAC阵列规模时我们确定频率500MHz目标算力16 TOPS那么每周期需要的整数运算次数是16e12 / 500e6 32000也就是每个时钟周期要完成32000次运算。因为一个乘累加单元一个周期完成2次运算一次乘法一次加法MAC数量取 16000 个。再按16x16的模块方案128个模块横着排就得到了设计规格。这个推导过程很枯燥但它是后续一切讨论的基础。1.2 片上存储与数据搬运的匹配计算MAC阵列的胃口只是半边。按上面的带宽估算如果所有数据都从外部DRAM来一个周期内需要16KB的输入在500MHz下约为8TB/s的带宽这显然不现实。于是我们把“可复用的数据留在片上”作为第二条硬约束。卷积层里每个输入特征图都会被多个输出通道共用如果编译器生成的调度能把这种复用显式暴露给DMA控制器就能把DRAM实际需求降到算力需求的十分之一以下。我们的优化目标是让片上SRAM容量刚好覆盖一层计算所需的全部中间激活和权重切片而不是想办法堆内存。在那个设计里选择了6MB的片上SRAM并配合三级DMA预取流水效果是实际DRAM带宽需求降到了约12GB/s。这里有个设计心得片上存储的容量选择不是做加法而是做“最极端层的满足度测试”。把模型里所有算子的活数据逐一过一遍选出峰值内存最大的三层用它们的范围去设定SRAM的下界这样既不浪费面积又不会出现某层跑不过去的尴尬。2. 计算阵列与数据通路为什么用MAC阵列全覆盖反而累赘定完主结构接下来是最容易引发软硬件两侧“长期拉锯”的部分计算阵列到底要多“通用”。我们的软件团队最初希望支持任意形状的二维卷积、转置卷积、空洞卷积甚至把上采样也吃进去。这个诉求听起来合理但硬件团队逐条估算晶体管代价后发现如果全部做成硬件直通核心面积至少膨胀35%而利用率可能下降15%以上。所以收敛的结果是硬件支持的是规则卷积和矩阵乘的基础原语剩下的非规则操作由编译器拆解成由多个规则操作组合而成的序列。这个分工背后其实是一条清晰的原则硬件做“确定性的高频动作”软件做“灵活但低频动作的解释器”。2.1 PE阵列内部的数据流选择PE阵列有两种典型的数据复用方式输出固定与权重固定。输出固定意味着每个PE轮流处理不同输入通道的加部分和权重寄存器可以长期保持。权重固定更适合卷积因为权重可以被多个输入位置复用减少片上寄存器文件的周转。我们最终选的是二者混合卷积带专用数据广播网矩阵乘则切换成输出固定模式。硬件上看起来只是多一组布线但编译器侧就得维护两种数据流描述。用代码看会更直观比如在编译器的IR阶段我们会给调度器增加一个数据流策略标记enum class DataflowType { OutputStationary, WeightStationary, RowStationary }; struct ConvConfig { DataflowType flow; int tile_width; int tile_height; int unfold_ratio; };这个结构体是整个编译后端的核心输入之一。调度器看到WeightStationary就会优先把权重块持久化到各PE寄存器然后让特征图数据按行广播。如果把unfold_ratio设为1意味着不做im2col展开卷积滑窗按照硬件广播网直接映射这能省掉大量中间张量搬运。2.2 片上网络与流水线的双重视角数据通路不只是电缆。我的习惯是把片上网络当作“缓存协议的一部分”而不是“简单的互联”。在5M SRAM分库后每个存储库的端口带宽不同而卷积和矩阵乘对存储带宽的需求也不同。这时候片上网络的作用不是平均分发而是依据编译器的访存模式做动态路由。我们做了一次很有意思的实测将网络拓扑从全互连改成“两簇局部互连加一根高带宽双向干道”面积少花了18%而典型模型性能只掉了约4%最终计算单位功耗性能反而提升了11%。这个结果直接说明了AI芯片数据通路不是越连通越好而是越匹配越好。软件侧为配合这条总线结构需要在地址映射上做“通道亲和性”优化把特征图A分配到与MAC阵列簇0直连的SRAM库矩阵乘B矩阵分配到簇1直连库而从干道另外一侧加载权重的DMA则单独占一根通道。这些地址规划虽然不起眼但在最终性能验证时明显减少了总线仲裁冲突流水线平均气泡率从12%降到了3%。3. 指令集与软硬件边界ISA设计是双方博弈的结果如果说架构是骨架指令集就是软硬件双方共同起草的合同。这个合同没法独断地由一方完成。硬件团队的本能是把每类算子做成一条封闭指令这样前端逻辑好写软件团队的本能则是把所有细节暴露给编译器这样优化空间最大。两边都有道理但我们最终以“可测试性”为收敛标准设计了轻量可组合的ISA。这版ISA不是长指令字也不是纯RISC风格而是一个带显式流水阶段标记的类RISC指令集每条指令在同一拍内只描述一个动作由编译器负责调度组合。这样做的最大好处是每一个行为都能被性能计数器精准追踪对后端的功耗和性能回归特别友好。3.1 指令规划的颗粒度我们在指令集设计上反复纠结的是计算指令要不要携带形状信息。早期方案里矩阵乘指令带上了M、N、K三个维度看起来能一次性算完一整块但编译器每次改变tile大小就要换一种指令代码生成的组合空间几乎是无穷的。后来改成基础语义指令比如load、store、conv、matmul、elementwise、pool、activate形状信息全部由寄存器配置描述。这样做之后一条矩阵乘的伪汇编看起来是这样的config_tile M32, N16, K8 load_weight acc_buf, weight_ptr, size4096 sync_dma wait_all matmul acc_buf, act_buf, weight_buf, modeINT8 elementwise act_out, acc_buf, relu store out_ptr, act_out, size512注意sync_dma这条指令它实际上在硬件里触发一级流水屏障。编译器在调度时会尽可能把后续的计算指令填入DMA搬运的空档但sync_dma总是被放在真正依赖数据的指令之前。这个机制让硬件可以乱序执行一部分操作但边界清清楚楚软件也在同步时知道数据已经就位。3.2 编译器后端的指令调度策略调度策略在工程上完全是统计驱动。我们要先在模拟器上采集指令组合的耗电和延迟再生成一个调度成本表作为后端启发式搜索的评价函数。具体算法我们采用了列表调度的加强版优先级函数里同时包含DRAM排队深度、SRAM复用距离和PE空闲率并在搜索窗口内做贪心回溯。这一个模块是整个项目里改动最频繁的。原因在于硬件设计稳定后性能爬坡几乎全靠编译器。曾经有一版调度器因为权重大小设置不合理把卷积层内部的数据复用顺序打乱了导致DRAM模组访问量增长了40%功耗直接超标。后来我们加了一个约束任何调度方案在生成后都要过一次“DMA冲突检查器”如果某个Bank被连续访问超过6次就强制插入一条等待指令并重新调整顺序。这个检查器其实反映的是一种设计哲学硬件是确定性的那么软件就必须在确定性之上做显式的约定。与其让硬件做复杂冒险预测不如让编译器把所有冒险装进自己的口袋里。这点对AI芯片尤其成立因为AI负载规律性极强统计特征比通用处理器明确得多硬件做预测器反而是一种浪费。4. 量化校准与编译器约定的跨层联动量化从来不是模型训练之后单独跑一遍的工具它是芯片设计流程里贯穿始终的契约。在硬件端INT8乘累加器的输出累加精度决定了后续是否需要额外的rescale指令在编译器端每一层算子的输入输出scale和zero point都必须对齐。很多团队等到片子回来才开始调量化结果发现某些层位的分布跟编译器假设的完全不同此时再改硬件已经来不及了。我们在这个项目里采用的做法是量化信息统一放在一个runtime配置表里编译器直接读取这个表生成中间表示而不是让量化模块生成一堆散落的scale参数。这张配置表通常长这样算子输入scale输出scalezero point运算模式conv10.0078120.015625128per-tensormatmul_30.0039060.0019530per-channeldepthwise_20.0156250.015625128per-channel这样设计有一个直接的好处编译器在做算子融合时可以顺着这张表判断“当前接口处是否需要rescale”。例如两个卷积直接融合时如果第一个的输出scale恰好等于第二个的输入scale编译器就能省掉一层quantize和dequantize操作。实测下来有这种联动设计的模型比没有联动时整体INT8推理时间平均缩短了22%。4.1 校准数据集的选择陷阱校准数据集的选取是最容易翻车的地方。有人喜欢用训练集的子集有人随机挑几张自然图都不太对。校准的目的是让各层的激活分布保持和真实推理接近因此要覆盖所有典型的数据形态最好还包括一些边界值。比如我们的多模态模型里有一路输入是低照度图像如果不把这类样本加进校准集激活值在低亮度区间会被严重截断导致INT8推理精度掉1.5个点以上。量化后的精度验证也要分场景。我一向主张对每个输出张量做逐bin的误差统计而不是只看最终精度。因为逐层误差统计能直接告诉编译器哪一层需要保留高精度累加哪一层可以激进地全部采用INT8计算且不损失任何性能。编译器根据误差表给出的“敏感度名单”动态切换某些算子的实际执行精度。4.2 量化参数如何指导硬件scale模块设计硬件上我们为每个PE旁边配了一个轻量rescale模块它的作用不是做复杂的浮点转换而是做一次定点移位加截断。如果量化配置表里统一使用2的幂次scale硬件甚至可以省掉乘法器直接用移位器完成转换。为了得到这个简化量化训练阶段我们对scale参数做了幂次约束。有人担心幂次约束会让模型精度不可接受实际测试显示在端侧视觉模型上用幂次约束做QAT精度损失通常在0.2%以内换来的是硬件面积节省约8%和每次rescale功耗减少60%。这个交换在边缘设备上非常划算。这个细节当初差点被砍掉后来量化团队用三组实验数据说服了硬件团队也让我更加确信跨层联动的前提是两边都得知道对方有哪些“便宜的参数约束”可以利用。5. 实测性能低谷的定位方式一次完整的性能排查片子回来后第一次跑全模型硬件利用率只有理论峰值的43%。当时大家第一反应是MAC阵列太慢但性能计数器把每一类指令的活跃周期打印出来后真相完全不同。查表的顺序是这样的统计项数值问题暗示MAC阵列有效周期43%计算本身大量空泡DMA等待周期31%数据到达不及时访存冲突周期18%多簇争抢带宽同步等待周期8%依赖链过长DMA等待占了31%很明显是“预取距离不够”。我们排查后发现编译器生成的DMA请求总是等到当前tile用完才开始发下一tile的搬运指令也就是没有做流水预取。这属于调度算法没有把“双缓冲”特性显式建模。解决方案是修改调度器的依赖分析把所有load指令允许提前到上一tile的计算完成之前而这时硬件上的SRAM双缓冲就能自动吸收两个tile之间的切换。这个改动在模拟器上看只提升了不到10%因为模拟器里的DRAM延时就假设得很好。但上了真实芯片后DMA等待周期从31%降到了9%MAC阵列利用率直接抬到76%。后续继续把片内缓存替换策略改成“按层调度”利用率才最终到80%。这也印证了那句话模拟器里看起来细微的差别到真实硬件上会被放大很多倍。5.1 性能计数器的设计要前置后面我复盘出一个重要经验性能计数器在设计阶段就要规划好不能等片子回来再补。为此我们在每个软件可感知的执行单元上挂了至少三类计数器指令分发计数、数据接受计数、写回计数。编译器还在IR阶段就定义了每个算子映射到计数器上的预期值跑完就能自动比对偏差。相比通用处理器AI芯片的数据流规律让这套做法非常顺手。你在做下一块芯片时千万不要把性能分析工具留到最后。否则所有怀疑都会落成“是不是MAC不够多”而不是回到指令调度的根因上去。没有计数器调优就是盲人摸象。5.2 现场调试的软件工具配合性能定位还需要一套能查看片上中间张量的调试工具。我们在驱动层加了一个快照接口可以让软件把SRAM里任意地址的内容拉出来与仿真器对比。有一次定位精度问题时就是通过快照接口发现某个通道的scale值跟配置表不一致根源是驱动在加载权重时把scale数组的字节序搞错了。这种bug如果光靠终端输出指标根本发现不了。快照接口的成本不高但它在片上调优阶段节省的时间是巨大的。这类工具建议在每个子系统都放一个包括DMA描述符、SRAM地址映射、MAC阵列中的寄存器配置。芯片回来后你一定会因为多看了这些底层细节而少熬几个通宵。6. 面向下一代架构的软硬件职责再分配项目结束后我们把这套设计里的几条分工经验抽象成了方法论准备用在下一版芯片上。这几天反复想觉得最值得分享的是下面几条硬件只做“高频且确定性”的操作其余全部交给编译器解释组合。指令集设计的终极标准不是功能完备而是“能查性能计数器就能定位问题”。量化参数的语义必须单一不干净的数据会导致编译器做出不可预判的优化。模拟器友好未必等于芯片友好凡是有条件尽量在早期跑通真实链路测试。我亲身经验是AI芯片的软硬件协同设计没有终点。每个版本都会在某个没想到的地方漏出水来但只要双方的接口契约足够清晰所有问题都能快速收敛到某一侧去解决。就我个人而言把这个接口契约文档当成“项目里优先级最高的产出物”来维护效果比任何架构评审都好。下一篇有机会的话我想把编译器后端里一套很少公开的“按层功耗感知调度”方法单独拿出来聊透那部分我们踩坑最深收获也最大。

相关新闻

JWT实现无状态SSO:从Token签发到登出的完整方案

JWT实现无状态SSO:从Token签发到登出的完整方案

单点登录(SSO)这个词,做过后端或架构设计的朋友一定不陌生。只要公司内部系统一多,就绕不开“一次登录,到处通行”的需求。但传统基于 Session 的 SSO 方案有个绕不过去的痛点:身份认证状态集中存在服务端&…

2026/10/12 21:57:04 阅读更多 →
汽车电子系统级芯片选型:开关、FPGA、MCU与SiC FET协同设计

汽车电子系统级芯片选型:开关、FPGA、MCU与SiC FET协同设计

1. 项目概述:四颗芯片背后的真实选型逻辑,不是参数表拼贴,而是系统级权衡你手头有四个型号:VNL5090S5TR-E、EP4CE10E22I7N、MCF51JM64VLD、UJ4C075023B7S。它们分属不同技术谱系——汽车级高边开关、Cyclone IV系列FPGA、ColdFire…

2026/10/12 21:57:04 阅读更多 →
C++调用MATLAB实战:Engine、Compiler SDK与Coder选型指南

C++调用MATLAB实战:Engine、Compiler SDK与Coder选型指南

1. 为什么要在C里调用MATLAB先把场景说清楚。你手上有一个用C写的主程序,可能是某个仿真系统、某个数据处理工具,或者某个需要长期稳定运行的服务端程序。同时,团队里有人用MATLAB把算法原型跑通了,里面有大量的矩阵运算、信号处理…

2026/10/12 21:57:04 阅读更多 →

最新新闻

RAG演进之路:从朴素检索到模块化架构的工程实践

RAG演进之路:从朴素检索到模块化架构的工程实践

在RAG(Retrieval-Augmented Generation,检索增强生成)这个方向上待得久一点,你会明显感受到一条演进曲线:早期大家忙着把检索和生成“拼起来跑通”,后来开始争论“检索要不要混合”“重排能不能救场”&…

2026/10/13 5:17:28 阅读更多 →
在COMSOL中构建水力压裂模型:固体力学与达西定律耦合全解析

在COMSOL中构建水力压裂模型:固体力学与达西定律耦合全解析

一说起水力压裂模拟,很多人第一反应就是“这个太专业了,是油田工程师的事”。但用COMSOL把水力压裂的完整过程落地成一个能跑的模型,其实比想象中要直接得多——核心就三件事:固体力学管地层怎么变形、达西定理管流体怎么渗流、两…

2026/10/13 5:17:28 阅读更多 →
LiteLLM 实战:用统一接口终结多模型接入混乱,实现路由与成本管控

LiteLLM 实战:用统一接口终结多模型接入混乱,实现路由与成本管控

大模型应用做到一定规模后,最让人头疼的往往不是模型效果,而是接入流程本身:A 家今天发了新 SDK,B 家明天改了限流策略,C 家的返回结构跟别家完全不一样,业务代码里的 if-else 越堆越厚,每换一次…

2026/10/13 5:17:28 阅读更多 →
Redis部署与性能调优实战:从选型到高可用缓存架构全解析

Redis部署与性能调优实战:从选型到高可用缓存架构全解析

前阵子给一个内部项目做缓存改造,目标是让一批热点读接口的延迟从300ms以上降到20ms以内。技术选型很快落到Redis上,毕竟它是目前生态最成熟的内存数据库,数据结构丰富、部署也算灵活。但真正动手做Redis 部署与使用的时候才发现,…

2026/10/13 5:17:28 阅读更多 →
集成与验证实战指南:从单元测试到端到端测试

集成与验证实战指南:从单元测试到端到端测试

/* 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 5:17:28 阅读更多 →
反编译避坑指南:伪代码可信度判断与类型重建实战技巧

反编译避坑指南:伪代码可信度判断与类型重建实战技巧

/* 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 5:16:28 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/12 21:05:09 阅读更多 →
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/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →