做视觉检测的同行应该都有体会训练一个YOLO模型从来不是难事真正磨人的是把模型塞进一块专门的推理卡里跑起来。最近因为一个边缘检测项目我花了整整一周时间把YOLOv5迁移到华为昇腾Atlas 300V上从烧录环境、装驱动、转模型到写推理代码踩了无数坑才把整条链路跑通。这篇文章就围绕“atlas部署yolo”这件事把我的操作过程、踩坑记录和调优心得全部整理出来也给还在纠结“atlas 300v 24g是不是运算加速卡”的朋友一个明确答案。如果你也正准备在昇腾平台上跑目标检测模型这篇应该能帮你省下不少时间。1. Atlas 300V到底是什么能不能跑YOLO1.1 先正面回答“是不是运算加速卡”这个问题先说结论Atlas 300V是AI推理加速卡不是传统意义上的“通用运算加速卡”。它和NVIDIA GPU的定位有本质区别GPU内部有几千个CUDA核心既能跑图形渲染也能做通用并行计算而Atlas 300V内部是昇腾310P芯片核心计算单元是AI Core主要针对神经网络算子做了硬件加速比如卷积、矩阵乘、归一化这类深度学习中最常见的计算模式。所以你问它是不是运算加速卡准确的说法是它是专门用于AI推理的运算加速卡。你用CPU跑图像分类也许能跑用GPU跑也许也能跑但用Atlas 300V跑前提是模型结构符合它支持的算子范围并且通过昇腾的软件工具链转换成它认识的文件格式。一旦转换成功它的推理性能和功耗比是通用GPU很难比的特别适合视频流分析、边缘盒子、推理服务器这类纯推理场景。这台卡有24GB大显存版本因为叫“atlas 300v 24g”所以很多人误以为它是类似Tesla T4那样的“小显卡”。实际形态上也确实像半高半长单槽PCIe接口装进机箱里不占地方。但它没有显示输出接口不能接显示器它纯粹是给神经网络推理当发动机用的。YOLO这种检测模型输入是图像输出是检测框和类别整个计算过程以CNN卷积为主恰好是昇腾AI Core最擅长的领域。1.2 硬件规格和算力到底怎么看Atlas 300V系列的公开规格大致是这样的不同批次和具体型号会有细微差异以你拿到手的那块卡的官方规格书为准项目典型规格核心芯片昇腾310P显存24GB LPDDR4XPro版25GBINT8算力约140-160 TOPSFP16算力约70-80 TFLOPS功耗70W左右接口PCIe 3.0 x16形态半高半长单槽很多人第一次看昇腾卡的规格都会一脸懵TOPS和TFLOPS到底代表什么简单说TOPS是每秒万亿次整数运算TFLOPS是每秒万亿次浮点运算。做AI推理时模型量化成INT8之后计算量会大幅压缩所以厂商更愿意在INT8指标上做文章。YOLOv5s这种模型FP16精度跑起来精度损失很小INT8量化后精度会有一点下降但对大多数检测任务来说完全够用。关键是INT8吞吐可以翻一倍以上这就是为什么部署YOLO时我更推荐在昇腾卡上跑INT8模型。24GB大显存的意义在于你不光能塞进一个YOLOv5s还能塞进YOLOv5l、YOLOv8x这种大模型甚至同时跑多个模型实例。我平时做视频分析一路1080p视频用YOLOv5s单模型推理显存只占几个GB剩下的空间还能开好几路并发卡资源利用率可以压得很高。1.3 为什么YOLO这类检测模型特别适合昇腾推理卡YOLO系列虽然版本众多从YOLOv3到YOLOv8核心结构从来没有离开过卷积、BN、ReLU/SiLU激活、残差连接这几个基础组件。昇腾310P的AI Core在设计时就针对这些算子做了深度优化卷积有专门的计算单元激活函数有向量单元来处理残差相加这类操作也能在片上完成。所以把YOLO模型搬到Atlas 300V上并不是什么奇技淫巧它就是这块卡非常典型的应用场景。另外还有一个重要原因YOLO的输入尺寸通常是固定的比如640乘640或320乘320。固定输入尺寸意味着模型在编译阶段可以做非常彻底的图优化把计算图里的常量折叠、算子融合、内存复用全部提前做掉运行时就能减少很多额外开销。昇腾的ATC工具干的就是这件事它把一个ONNX模型翻译成针对具体芯片优化后的离线模型文件.om运行时直接加载这个优化后的图不需要像GPU那样在运行时做动态算子调度。当然也不是说YOLO模型随便导出就能在Atlas 300V上跑。你得让模型的算子完全落在昇腾算子库支持的范围内一旦出现不支持的算子模型转换就会卡住。这一点放到后面的部署流程里详细说。2. 部署前必须搞清楚的软件栈与选型2.1 昇腾部署的三层软件结构在Atlas 300V上跑模型不是装个驱动就能完事的。昇腾平台有一套自己的软件栈从底到上大致分三层底层是驱动和固件HDK中间是AI计算平台CANN最上面是应用层接口。驱动和固件负责让操作系统认到这块卡管理硬件资源类似GPU的Driver。CANNCompute Architecture for Neural Networks就相当于CUDA加cuDNN的组合它提供算子库、模型编译器、运行时管理这些核心能力。没有CANN你就算把模型转好了也没法跟硬件打交道。最上面的应用层就是你自己写的推理代码可以用CANN暴露的Python/C接口也可以借助更上层的开发工具。我把这套结构比作集装箱码头硬件是港口固件驱动是港口的基础设施CANN是装卸货物的机械臂和调度系统你的模型就是那个集装箱最后写的那段推理代码就是告诉你哪个箱子搬到哪辆车的工单。任何一个环节没配对货就卡住了。部署踩坑第一课安装顺序不能乱。一定要先装驱动固件确认系统能识别到卡再装CANN。反过来装CANN检查不到硬件或者版本不匹配后面所有命令都会报一堆莫名其妙的问题。2.2 环境安装的具体步骤以常见的x86服务器加Ubuntu 20.04系统为例昇腾卡的安装流程大致如下。首先从昇腾社区下载对应的驱动固件包和CANN工具包下载时要看清版本对应关系比如CANN 7.0对标的驱动固件版本是多少。我踩过的坑是直接下载了最新版本结果驱动和CANN版本不匹配CANN自带的检查工具直接报错。安装命令本身不复杂核心几步# 安装驱动固件包 ./Ascend-hdk-xxx.run --install # 查看驱动是否安装成功 npu-smi info # 安装CANN工具包 ./Ascend-cann-toolkit_xxx.run --install # 设置环境变量建议写进 ~/.bashrc source /usr/local/Ascend/ascend-toolkit/set_env.shnpu-smi info这个命令非常关键它类似NVIDIA的nvidia-smi。执行后能看到卡的负载、温度、显存使用情况还能看到芯片型号和固件版本。如果你执行npu-smi报错大概率是驱动没装好或者系统内核版本不兼容。我遇到过内核升级后驱动加载失败的情况解决办法是回退内核版本或者重装与内核匹配的驱动包这个坑在全新安装时尤其容易踩。装完CANN后记得验证一下Python接口是否可用python3 -c import acl; print(acl.__version__)如果能正常导入acl模块说明CANN的Python接口已经就绪。有些环境还需要装配套的Python依赖比如numpy、pyyaml这些常规库。2.3 工具链选型ATC加pyACL还是MindX SDKCANN之上有几种选择常见的有三条路一条是ATC工具做模型转换然后直接用pyACL或者C的ACL接口写推理代码一条是用MindX SDK它是昇腾封装好的一套媒体处理加推理的流水线组件还有一条是用MindIE主要面向大模型推理服务化对YOLO来说有点重。我的建议是如果是部署YOLOv5、YOLOv8这类自定义后处理很灵活的检测模型直接走ATC加pyACL这条路。原因很简单MindX SDK虽然内置了目标检测插件但它对YOLO系列的支持滞后于模型迭代速度版本匹配和算子适配经常踩坑。而且检测模型的后处理NMS逻辑各不相同自己在代码里实现反而更可控。ATC加pyACL这条路更接近“原生开发”的感觉ATC负责把ONNX模型编译成昇腾卡认识的om文件pyACL负责加载om文件、管理内存、执行推理、取回结果。后处理部分自己写灵活度高调试也方便。如果你要做成服务后面再把pyACL封装成GRPC或者HTTP接口就行。3. 完整跑通一个YOLOv5部署流程3.1 从训练好的模型到ONNX文件假设你已经在PyTorch里训练好了一个YOLOv5模型部署的第一步是把它导出成ONNX格式。YOLOv5官方代码仓库自带export.py脚本命令很简洁python export.py --weights yolov5s.pt --include onnx --opset 13这里有几个关键点要注意。第一opset版本建议选13或17但选之前先确认你安装的CANN版本支持到什么程度。我刚开始用opset 17导出ATC转换时碰到一个算子兼容问题后来改用opset 13就顺利过了。如果你对CANN版本支持情况不熟opset 13是比较稳妥的选择。第二导出ONNX时一定要把后处理部分剥离掉。YOLOv5的原生导出支持带NMS的版本但那个NMS模块在昇腾卡上转换难度大、性能也差。你只需要导出一个纯推理模型输入是图像Tensor输出是三个尺度的预测特征图后处理留到推理代码里自己做。这样ATC转换更容易通过运行时Flexibility也更高。第三强烈建议用onnxsim对导出的ONNX模型做一遍简化。这个工具会把多余的Reshape、Transpose节点清理掉把常量折叠掉生成的模型更干净。ATC编译时面对一个干净的图编译效率和成功率高很多。python -m onnxsim yolov5s.onnx yolov5s_sim.onnx如果你的模型是YOLOv8流程类似ultralytics仓库也提供了export.py导出时同样建议去NMS、固定输入尺寸、用onnxsim简化。3.2 ATC模型转换把ONNX变成om得到简化后的ONNX模型后下一步就是用ATC工具把它编译成昇腾卡能加载的om离线模型。ATC命令的基本格式如下atc --modelyolov5s_sim.onnx \ --framework5 \ --outputyolov5s_om \ --soc_versionAscend310P3 \ --input_shapeimages:1,3,640,640 \ --input_formatNCHW \ --output_typeFP16参数拆开解释一下。--framework5表示输入模型是ONNX格式。--output指定输出文件名。--soc_version非常关键它告诉ATC你的目标芯片是哪个型号这个参数填错了转换也能成功但加载到卡上会报型号不匹配错误。Atlas 300V基于昇腾310P芯片一般填Ascend310P3怎么确认最简单的方式是看npu-smi info输出里的芯片型号或者看CANN安装目录下的文档说明。--input_shape需要和你的导出模型保持一致。如果导出时输入名是images、尺寸是1x3x640x640那这个参数就按这个填。这里有个细节我建议直接固定batch为1先跑通整条链路。后面做性能优化时再考虑动态batch或者多batch。--output_typeFP16表示模型输出是FP16类型。推理后拿回来的数据是FP16在CPU端做后处理numpy运算时会自动转成float32只要在代码里cast一下就行。如果你想省心一点这里也可以设成FP32代价是推理后处理时数据量大一点性能略受影响但初期调试阶段无所谓。ATC转换成功后会生成一个.om文件。如果转换过程中报错最常见的提示是某个算子不在支持列表里。解决办法后面专门讲。3.3 写一个能跑的pyACL推理脚本模型转好后核心就是写推理代码。pyACL的使用逻辑和CUDA很像先初始化、开设备、创建context和stream然后加载模型、准备输入输出内存、执行推理、取结果。下面是一段能跑通的骨架代码import acl import numpy as np # 初始化 acl.init() ret acl.rt.set_device(0) context, ret acl.rt.create_context(0) stream, ret acl.rt.create_stream() model_id, ret acl.mdl.load_from_file(yolov5s_om.om) # 准备输入输出 input_data np.random.randn(1, 3, 640, 640).astype(np.float16) # 这里实际应该用letterbox处理后的真实图像 input_tensor, ret acl.rt.malloc(input_data.nbytes) acl.rt.memcpy(input_tensor, input_data.nbytes, input_data.data_ptr(), input_data.nbytes, acl.rt.ACL_MEMCPY_HOST_TO_DEVICE) # 创建输出数据集 output_desc acl.mdl.create_output_desc(model_id) output_size acl.mdl.get_output_size_by_index(model_id, 0) output_tensor, ret acl.rt.malloc(output_size) # 执行推理 acl.mdl.execute_async(model_id, [input_tensor], [output_tensor], stream) acl.rt.synchronize_stream(stream) # 取回结果 output_data np.zeros(output_size, dtypenp.uint8) acl.rt.memcpy(output_data.data_ptr(), output_size, output_tensor, output_size, acl.rt.ACL_MEMCPY_DEVICE_TO_HOST) # 释放资源 acl.rt.free(input_tensor) acl.rt.free(output_tensor) acl.mdl.unload(model_id) acl.rt.destroy_stream(stream) acl.rt.destroy_context(context) acl.rt.reset_device(0) acl.finalize()这段代码只是演示核心流程没有处理多输出、也没有封装错误检查真正工程化时每个ret返回值都要判断否则出错时你根本不知道卡在哪一步。YOLOv5模型有三个输出头实际代码里需要为三个输出分别创建输出Tensor并记录每个输出的shape和数据类型。预处理部分是你真正要用心写的地方。图像的resize方式要和训练时保持一致。YOLOv5训练时用的是letterbox也就是等比例缩放后给四周补灰边不是直接拉伸。推理脚本里pipeline一般是读图、letterbox到640乘640、BGR转RGB、HWC转CHW、归一化到0到1、转成FP16、执行推理。后处理部分也不简单。模型输出的是三组特征图每组对应一个尺度的检测结果。你需要按YOLOv5的标准解码流程把坐标、置信度、类别概率解出来经过阈值筛选和NMS后得到最终检测框。如果解码逻辑写错了模型推出来的结果会乱七八糟先不要怀疑硬件和模型转换有问题先检查后处理。这里分享一个调试技巧拿到om模型后先用一张训练集里的图片跑一遍把模型原始输出打印出来分别用gpu上的结果和atlas出来的结果对比。两者输出的特征图应该有误差但整体趋势一致。如果不一致优先检查预处理是否和训练一致如果一致问题基本就出在后处理代码上。3.4 实测性能参考和瓶颈判断我在自己的测试环境上跑YOLOv5s输入640乘640FP16精度单batch单卡实测延迟大概在5到8毫秒量级帧率能稳定跑在120到200 FPS之间。这个数字不算惊艳但考虑到卡的功耗只有70W左右能效比非常可观。换INT8量化模型后延迟还能再降一截吞吐量提升明显。刚跑通时很容易觉得卡很慢因为你看到的延迟数字包含了预处理和后处理的时间。实际上模型推理本身很快吃时间的大头经常是后处理的NMS。我遇到过推理只要3毫秒但numpy写的NMS要跑6毫秒的情况整体帧率被砍了一半。优化思路有两个一是把NMS写得向量化一些避免用纯Python循环二是合理设置置信度阈值从源头减少进入NMS的候选框数量。这些小细节对最终吞吐影响非常大。4. 部署过程中最常踩的坑4.1 模型转换环节的典型问题ATC转换是整个流程中报错最密集的环节我遇到的典型问题整理成了这个表方便你对照排查现象常见原因解决办法报错提示算子不支持ONNX模型里有昇腾算子库未覆盖的算子用onnxsim简化模型更换opset版本检查自定义算子转换成功但加载报错soc_version和实际芯片不匹配用npu-smi info确认芯片型号输入输出shape对不上input_shape参数或输出节点配置错误用netron查看ONNX模型输入输出节点生成om文件大小异常巨大模型里包含动态shape导致编译展开很多分支固定输入尺寸避免动态shape推理结果全错预处理不一致或有未知的格式转换检查颜色通道顺序和归一化参数算子不支持的坑最常见。YOLO模型里的SiLU激活函数在旧版本CANN里支持得不好解决办法是换CANN版本或者换opset版本。还有一个小经验导出ONNX后多跑几个不同的简化方式有些时候onnxsim一把梭不够还需要用onnx_graphsurgeon做更精细的图修改特别是把输出节点裁剪干净。4.2 推理运行时的各种疑难杂症模型转换成功只是第一步运行时的坑更多。我第一个遇到的运行时问题是推理结果输出全为0或者NaN。排查了大半天最后发现是预处理时把图像通道顺序搞反了用了BGR数据但模型训练时用的是RGB。这个“颜色通道三行代码”问题是部署检测模型时最容易犯的错误没有之一。第二个典型的运行时问题是内存相关比如进程启动时申请设备内存失败或者连续跑几百次后内存越涨越高。这个是典型的资源泄漏pyACL里每次推理如果都调acl.rt.malloc申请输入输出内存用完必须调acl.rt.free释放。如果只是申请不释放短时间内看不出问题跑上几千次后系统内存和显存都会被吃满。我自己的做法是在初始化阶段把输入输出buffer全部申请好推理时反复复用只有在图像尺寸变化时才重新申请。还有一个问题更容易忽略多线程并发推理。Python里用多线程跑pyACL推理由于全局解释器锁的存在纯计算部分不会加速但如果把线程用在多个模型的并发调度上逻辑上还是能提升整体吞吐的。不过我遇到过多个线程同时调用同一个context时偶发崩溃的情况后来给每个线程单独建context和stream才解决。这个细节你在做并发服务时一定要留意。4.3 提升吞吐量的几个实用技巧第一招是使用多batch推理。模型转换时input_shape里把batch从1提到4或者8推理时一次传入多张图芯片的利用率会高很多。图像处理场景经常是一次来一帧视频那就需要在应用层做缓存和攒批攒够4帧再一起送进去。虽然延迟会稍微增加但吞吐提升非常可观。第二招是把预处理下沉到AIPP。CANN的AIPP功能可以让你在模型输入之前让卡上的硬件模块自动完成裁剪、缩放、色域转换、归一化这些操作。这样CPU端只需要做图像解码和内存拷贝resize、normalize这些高频操作全部交给硬件能释放不少CPU占用。配置AIPP需要在ATC转换时加一个aipp配置文件里面指定输入图片格式、缩放尺寸、归一化均值方差等参数我实践下来效果非常明显。第三招是NMS后处理并行化。如果单路视频推理只需要几十FPS后处理用Python勉强能扛。但如果你要跑十几路视频流后处理立刻变成瓶颈。建议把NMS逻辑从Python改写成numpy向量化版本或者直接调用opencv的DNN模块里的NMS函数速度能快一个数量级。更进一步的方案是把NMS也放到卡上用自定义算子实现但开发成本高一般遇到极高性能要求才需要做。5. 部署完成之后一块卡到一套服务5.1 封装成标准推理服务跑通单张图片推理后应该顺手把代码封装成一个可复用的服务。我的做法是用FastAPI包一层HTTP接口外部传入图片字节流服务内部做解码、预处理、推理、后处理最后返回检测框JSON结果。HTTP接口的好处是跨语言跨平台不管接Web后端还是边缘盒子上的视频流分析程序都很方便。如果是高吞吐场景更推荐用gRPC。HTTP接口每帧都有网络协议开销gRPC在长连接、二进制传输上效率高很多。我在做16路视频流分析时gRPC方式比HTTP方式整体延迟降低大概两成左右。框架选定之后还要把内存复用和模型常驻这两件事做好模型只加载一次所有请求共享同一个模型实例避免每次请求重新加载om文件。5.2 从YOLOv5扩展到其他模型这套流程不只适用于YOLOv5YOLOv8、YOLOX、RT-DETR这些检测模型都可以照着同样的思路迁移。YOLOv8导出ONNX后模型输出节点的数量和格式跟YOLOv5不一样但ATC转换参数基本大同小异主要工作量在后处理解码部分。RT-DETR本身带了Transformer结构对昇腾算子支持的要求更高一点实测需要CANN版本比较新才能顺利转换。我在实际项目中还跑过一些实例分割模型比如YOLOv8-seg、Mask R-CNN这类。分割模型输出除了检测框还会多一路mask输出解码逻辑更重但整体链路没有本质区别。只要模型能导出成ONNX并且所有算子都在昇腾算子库的覆盖范围内迁移到Atlas 300V上基本就是时间问题。5.3 最后分享一点个人体会跑完整个项目后回头看在Atlas 300V上部署YOLO这件事真正难的不是用卡而是把训练生态和推理硬件这两套体系之间的缝隙填平。PyTorch训练好的模型要经过导ONNX、图形简化、算子对齐、ATC编译、pyACL推理、后处理复刻这一整套流程才能跑起来。任何一环出问题报错信息都不够直白需要你自己一点点排查。我的体会是做昇腾卡部署一定要沉住气尤其第一周各种版本不匹配、算子不支持、结果异常是真的磨人。但你只要完整跑通一个模型后面再部署第二个、第三个就轻车熟路了。现在昇腾的软件生态比前两年完善了不少文档和社区案例也越来越多学习成本已经降低了很多。如果你准备上手Atlas 300V别急着写代码先把环境版本关系理清楚再把模型转换流程跑通后面的事情都会顺利很多。
企业数字化 ERP 产品动态
相关推荐
FreeRTOS多线程程序设计实战:任务划分、优先级与稳定性优化 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 5:14:06
日志分析实战:从IIS日志到SQL盲注的渗透链路 1. 项目概述:从一道CTF赛题看日志分析的实战逻辑链“[闽盾杯 2021]日志分析 WP”这个标题,乍看像一份赛后复盘文档,但背后是一整套Web安全攻防中极为关键的“非交互式渗透路径”——它不靠前台表单注入,不依赖用户点击,… · 2026/9/26 5:14:06
CiLocks 6位PIN爆破耗时推算:为什么它几乎不可行,如何聪明地缩短时间 CiLocks 6位PIN爆破耗时推算:为什么它几乎不可行,如何聪明地缩短时间 【免费下载链接】CiLocks Crack Interface lockscreen, Metasploit and More Android/IOS Hacking 项目地址: https://gitcode.com/GitHub_Trending/ci/CiLocks
CiLocks 是一款… · 2026/9/26 5:14:06
Jetpack Compose 重组优化实战:稳定性、状态设计与性能调优 用 Jetpack Compose 写界面半年之后,我发现自己最怕的不是布局逻辑写不出来,而是列表一滑就掉帧、输入一打字就整屏闪烁。这些问题的根源,几乎都指向同一个词:重组优化。Compose 的重组(recomposition)是声… · 2026/9/26 6:16:48
基于Spring Boot和Vue的走失儿童认领登记系统设计与实现 搞 JavaWeb 毕设的同学,十个里有八个会选这类“信息登记 审核流程”方向,走失儿童认领与登记系统更是常客。标题里写着“宝贝回家”,听着很有社会价值,实际做起来却没那么浪漫——它本质上是一套给家属、管理员、认领申请人用的多… · 2026/9/26 6:16:48
MinIO社区版精简部署指南:从资源优化到替代方案 上礼拜一个朋友问我,他刚在一台“精简版”Windows 11上把系统折腾干净,顺手想搭一个私有对象存储,结果MinIO一启动内存就飙,问我要不要去下个“精简版MinIO”。我说,你问的这个问题,大部分人其实问的都不是… · 2026/9/26 6:16:48
FDE工程师真实面貌:现场交付、技能树与避坑指南 1. 别急着骂“洋概念”,先分清你骂的到底是哪个FDE最近“FDE”这个词在职场社交平台和培训广告里出现得越来越频繁,什么“FDE解决方案工程师(高级)”、“腾讯FDE课程”、“FDE证书报名”,看起来高大上,点进… · 2026/9/26 6:16:48
芯片完整性筛查新思路:电源侧信道功耗指纹识别 芯片完整性验证这件事,绝大多数现有方案都有一个共同前提:芯片会老老实实回答你。设备上电之后发一句“报告身份”,芯片返回一串ID;或者去读它的boot flash,和出厂哈希比对一下。问题是,如果环节里的某个角… · 2026/9/26 6:16:48
SpringBoot学生成绩动态追踪系统:从趋势分析到学业预警与可视化大屏 做学生成绩管理系统,很多人第一反应就是增删改查,无非是把Excel搬到网页上。但你真正去面对一个高校的学业管理需求时,会发现事情远比想象中复杂:成绩数据零散、排名变动说不清、辅导员没法及时知道哪些学生出了问题、学生自己也不… · 2026/9/26 6:16:42
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46