1. Atlas 300V 24G 到底是什么卡先说结论Atlas 300V 24G 是华为昇腾系列里面向AI推理场景的运算加速卡但它不是传统意义上的游戏显卡或通用计算GPU而是一张以昇腾 AI Core 为核心处理器、专门为神经网络推理任务设计的加速设备。我第一次拿到这块卡的时候第一反应也是找显存、找CUDA核心数量结果发现完全不是那套玩法。它板载 24GB 内存这里用的是标准 DDR4 规格而不是GPU常用的 GDDR6 或 HBM这一点和普通显卡有本质区别。它通过 PCIe 接口插在服务器或工作站上典型的功耗在 70W 左右半高半长的单槽规格非常适合放在 1U/2U 机架式服务器里做密集部署。很多人会问它能不能做训练我的回答是可以但不推荐。Atlas 300V 系列的设计目标是极致推理性价比在 INT8 精度下能提供很强的算力但 FP16/BF16 的训练场景算力会弱不少。如果你要做大规模训练建议选择 Atlas 训练卡或专用的训练服务器如果是要把训练好的 YOLO 模型部署到生产环境做实时推理那 300V 24G 是很合适的选手。这块卡的核心价值可以拆成三点高能效比24G 大内存 INT8 加速适合同时加载多个模型实例或处理大分辨率输入低功耗低成本一张卡 70W 左右一台 2U 服务器能插 8 张卡部署密度和电费都非常友好昇腾生态闭环从模型转换到推理部署用的是 CANN 工具链和 MindSpore 生态国产化场景落地很稳。我实际测试下来用 Atlas 300V 24G 部署 YOLOv5s 模型输入分辨率 640x640INT8 量化后单卡吞吐能做到 100 FPS 以上这个表现用于工厂质检、安防监控、明厨亮灶这类场景完全够用。2. 部署 YOLO 的整体思路与工具链选型2.1 为什么需要模型转换而不是直接推理用过昇腾卡的朋友应该清楚Atlas 300V 不能直接跑 PyTorch 的 .pt 权重而是需要先把模型转换成昇腾专用的 OM 格式。原因是昇腾 AI Core 的指令集和硬件流水线和 GPU 完全不同PyTorch/ONNX 这类框架的算子需要映射到 CANN 的算子库再由 ATC 工具完成图优化、算子调度、内存复用等一系列编译工作。这里可以类比一下GPU 的生态是 NVIDIA 花十几年搭好的PyTorch 里调用 torch.cuda 就能直接跑但昇腾走的是另一条路需要用 CANN 的模型转换工具把通用模型翻译成昇腾硬件能高效执行的中间表示。翻译得好不好直接决定最终推理性能。整个部署链路是这样的PyTorch/.pt 权重 - ONNX 导出 - ATC 模型转换 - .om 文件 - MindX SDK / pyACL 推理实际项目中我一般用 YOLOv5 或 YOLOv8 训练然后把模型导出为 ONNX再通过 ATCAscend Tensor Compiler转成 OM 格式。ONNX 是中间桥梁它把模型的计算图用一种硬件无关的方式描述出来ATC 再针对昇腾硬件做优化。2.2 CANN、MindX SDK、pyACL 怎么选CANNCompute Architecture for Neural Networks是昇腾的底层软件栈相当于 CUDA 之于 NVIDIA。CANN 里包含驱动、运行时runtime、算子库、图编译工具等是必须安装的基础环境。MindX SDK 是昇腾上层封装好的推理开发套件提供了基于插件的流水线式开发模式。它把图像解码、缩放、模型推理、后处理这些环节封装成了一个个 plugin你用配置文件把它们串起来就能跑通一个推理服务开发周期非常短。pyACL 则是 CANN 的 Python 接口偏底层灵活性最高。如果你想在推理前后做高度自定义的预处理或后处理比如复杂的 NMS 逻辑、多模型串联、自定义 ROI 提取那用 pyACL 会更顺手。我的建议是快速验证、业务逻辑简单优先用 MindX SDK省事需要深度定制、性能调优用 pyACL 自己写推理管线团队里算法工程师多、需要频繁改模型直接用 pyACL 封装一个推理服务方便迭代。2.3 硬件参数与算力匹配分析Atlas 300V 24G 的具体参数这里列一份实测对照表方便大家做选型参考参数项Atlas 300V 24G 实测值说明板载内存24GB DDR4可用内存约 22GB内存带宽约 100GB/s与 GDDR6 有差距但推理场景够用INT8 算力约 140 TOPS峰值值实际要打折扣FP16 算力约 70 TFLOPS用于混合精度推理功耗典型 72W满载约 80W 出头接口PCIe 3.0 x16注意服务器要留足 PCIe 通道外形半高半长单槽适合高密度部署关于24G 大内存能干什么我在项目里主要用到两个方向大分辨率输入比如 YOLO 直接跑 1280x1280 输入或者 4K 图像切块后多路并行处理多模型多实例把多个不同场景的模型同时加载到一张卡上比如同时跑 YOLOv5s 检测、ResNet18 分类、OCR 识别完全不会内存溢出。需要补充说明的是24G 内存不代表 24G 都是给模型权重用的。实际推理时内存还要存放输入图像、中间特征图、输出结果以及运行框架的缓存所以设计模型并发路数时不要把内存算满建议预留 20% 的安全余量。3. 实操部署 YOLOv5 全流程3.1 环境准备与版本匹配昇腾部署最怕的就是版本不匹配。软件栈分为驱动、固件、CANN toolkit、MindX SDK 几个部分版本之间互相有依赖关系装错了会出现各种奇怪的问题。我当前项目使用的版本组合是组件版本备注操作系统Ubuntu 20.04.6 LTS x86_64ARM 服务器也支持但命令略有差异驱动23.0.3对应 AscendHDK 包固件23.0.3与驱动同版本配套CANN toolkit7.0.0.RC1包含 ATC、pyACL 等核心工具MindX SDK5.0.RC2如果走 SDK 路线需要装Python3.8 / 3.9 均可建议 3.8兼容性最好安装驱动的步骤这里不展开重点说一下安装完成后的验证命令npu-smi info如果能看到如下信息说明驱动和固件正常-------------------------------------------------------------------------------------------- | npu-smi 23.0.3 Version: 23.0.3 | ------------------------------------------------------------------------------------------ | NPU Name | Health | Power | |-------------------------------|-----------------|------------------------------------------| | 0 Atlas 300V | OK | 72W | ------------------------------------------------------------------------------------------注意看到 Health 状态是 OK 还不够还要检查 npu-smi info 里的内存信息是否显示 24GB。很多次环境准备看起来成功实际是卡没被正确识别内存显示 0这种情况需要重新检查供电和 PCIe 插槽。3.2 模型导出 ONNX我以 YOLOv5 为例因为它的 ONNX 导出最成熟。在训练完成的模型目录下执行python export.py --weights runs/train/exp/weights/best.pt --include onnx --opset 12 --simplify这里有两个关键参数--opset 12ONNX 算子集版本CANN 对 opset 12 的支持比较完善太高版本可能会遇到不支持的算子--simplify用 onnx-simplifier 对计算图做简化去掉一些冗余的节点能显著减少后续 ATC 转换时的报错概率。导出的 YOLOv5 原始 ONNX 包含三个输出头分别对应 80x80、40x40、20x20 三个尺度的特征图。每个输出头的 shape 一般是[1, 25200, 85]COCO 数据集 80 类 4 个框坐标 1 个置信度。如果你想在模型里就把 NMS 环节做进去可以在导出时加上--end2end参数这样生成的 ONNX 会包含 NMS 算子推理时可以直接输出最终检测框。但这里有个坑CANN ATC 对 End2End 模型的支持不太稳定尤其是自定义的 NMS 后处理逻辑我在实际项目中踩过几次坑后还是选择在模型外做 NMS这样更稳调试也方便。3.3 ATC 模型转换拿到 ONNX 文件后使用 ATC 工具转换成昇腾的 OM 格式。这一环节是整个部署流程的核心转换参数直接决定后续性能。最基本的转换命令atc --modelyolov5s.onnx \ --framework5 \ --outputyolov5s_bs1 \ --input_formatNCHW \ --input_shapeimages:1,3,640,640 \ --soc_versionAscend310P3 \ --insert_op_confaipp.cfg \ --precision_modeallow_mixed_precision逐个参数解释--model输入 ONNX 文件路径--framework55 表示 ONNX这个参数容易漏漏了会报错--output输出 OM 文件名前缀--input_shape静态输入的 shape这里1,3,640,640对应 batch 1、RGB 三通道、分辨率 640x640--soc_version硬件平台版本。Atlas 300V 24G 对应的是 Ascend310P3这个不能填错填错了虽然也能转换成功但部分算子无法达到最优调度性能会打折扣--insert_op_confAIPP 配置文件用于图像预处理的下沉--precision_mode精度策略。allow_mixed_precision表示混合精度算子在 FP16 和 FP32 之间自动选择精度损失很小收益明显。AIPP 配置aipp.cfg是重点它可以把图像的缩放、减均值、除以标准差这些预处理直接放到硬件上做不需要在 Python 侧逐帧处理能节省不少 CPU 消耗。我的 aipp.cfg 配置如下aipp_op { aipp_mode: static input_format: RGB888_U8 src_image_size_h: 640 src_image_size_w: 640 csc_switch: true rbuv_swap_switch: false min_chn_0: 0 min_chn_1: 0 min_chn_2: 0 var_reci_chn_0: 0.003921569 var_reci_chn_1: 0.003921569 var_reci_chn_2: 0.003921569 }这段配置的含义是输入图像是 RGB888 格式宽高 640x640减均值 0、乘系数 1/255相当于在硬件层面完成归一化。这样 Python 端只需要做图片解码和 Resize不需要再做归一化计算。转换完成后会生成yolov5s_bs1.om文件用omg或者 ATK 工具可以查看模型信息omg --modelyolov5s_bs1.om --outputinfo.txt实际建议在转换时固定 batch。YOLOv5 导出 ONNX 时默认 batch 是 1如果你想在推理时支持动态 batch需要在导出时指定--batch-size 4或转换时使用动态 shape。但从性能和内存占用角度考虑我建议生产环境固定 batch用多路并发代替动态 batch调度更稳定。3.4 基于 pyACL 实现推理代码完成模型转换后接下来可以写推理代码。这里给出一个基于 pyACL 的最小实现框架方便理解整个调用流程。import acl import numpy as np import cv2 # 初始化 ACL acl.init() ret acl.rt.set_device(0) context, ret acl.rt.create_context(0) # 加载模型 model_path byolov5s_bs1.om model_id, ret acl.mdl.load_from_file(model_path) # 获取模型输入输出信息 input_desc acl.mdl.create_desc() acl.mdl.get_input_desc(input_desc, model_id, 0) input_size acl.mdl.get_input_size_by_index(model_id, 0) output_desc acl.mdl.create_desc() acl.mdl.get_output_desc(output_desc, model_id, 0) output_size acl.mdl.get_output_size_by_index(model_id, 0) # 分配 device 内存 input_data np.zeros((1, 3, 640, 640), dtypenp.float32) input_ptr acl.rt.malloc(input_size, 2) acl.rt.memcpy(input_ptr, input_size, input_data.ctypes.data, input_size, acl.rt.MEMCPY_DEVICE_TO_DEVICE) output_ptr acl.rt.malloc(output_size, 2) # 模型推理 stream acl.rt.create_stream() acl.mdl.execute_async(model_id, [input_ptr], [output_ptr], input_size, output_size, stream) acl.rt.synchronize_stream(stream) # 将输出拷贝回主机端 output_data np.zeros(output_size, dtypenp.uint8) acl.rt.memcpy(output_data.ctypes.data, output_size, output_ptr, output_size, acl.rt.MEMCPY_DEVICE_TO_DEVICE) # 解析输出reshape 成 3 个特征图 output_arr np.frombuffer(output_data, dtypenp.float32) # ... # 清理资源 acl.rt.free(input_ptr) acl.rt.free(output_ptr) acl.mdl.unload(model_id) acl.rt.destroy_context(context) acl.rt.reset_device(0) acl.finalize()代码逻辑并不复杂核心就三步加载模型、准备输入输出内存、执行推理。真正的工程难点在后处理部分需要把 ONNX 输出的三个尺度的特征图拼接起来解码出框坐标、置信度和类别再做 NMS。后处理我建议用 numpy 或者 PyTorch 实现直接调用 torchvision.ops.nms 就行避免自己造轮子。3.5 推理结果的可视化验证推理跑通后第一件事不要急着上生产先用几张测试图片验证结果是否正确。我是这样验证的用同一个测试集分别用原版 PyTorch GPU 推理和 Atlas 300V 推理把两边的检测框画出来对比对比 IoU 大于 0.5 的框数量是否一致判断转换是否出错特别注意置信度分数是否变化过大如果 INT8 量化后置信度普遍低于原版 FP16 模型 0.35 以下说明量化校准没做好需要重新处理。我这里实际对比结果混合精度模式下YOLOv5s 的 mAP 下降不到 0.5 个点置信度分数几乎无感。如果做全 INT8 量化mAP 会下降 1-2 个点但对大多数业务场景没有影响。4. 实战中的性能调优与踩坑经验4.1 算子性能分析与内存优化Atlas 300V 的性能调优核心思路和 GPU 类似但手段有差异。首先要会用 profiling 工具定位瓶颈。CANN 提供 msprof 工具能采集算子耗时、内存使用、数据搬运的详细数据。msprof --applicationpython infer.py --output./msprof_result跑完后会生成 trace 文件用 msprof 自带的解析工具打开能看到每个算子的执行时间。我的调优经验是优先看数据搬运耗时占比。昇腾 AI Core 算得快但数据在内存和 AI Core 之间的搬运开销往往比计算本身还要大。如果发现数据搬运占比过高优化方向有两个使用 AIPP 把图像预处理下沉到硬件减少 H2DHost to Device数据量和多次搬运用异步推理 多线程预处理把解码、Resize、推理重叠加起来让硬件一直在干活。我实测下来YOLOv5s 640x640 输入单张图像纯推理耗时约 8-10ms但如果算上图像解码和预处理端到端单帧耗时可能到 15-20ms。通过 AIPP 下沉预处理后端到端耗时能降到 12ms 左右性能提升明显。其次内存复用也要注意。pyACL 的 inference 如果频繁申请、释放 device 内存会有不小的开销。实际项目中我会预分配一个内存池推理过程中循环复用同一块输入输出内存这样避免了频繁的 malloc/free。# 提前分配好 input/output buffer # 推理循环内部只做 memcpy 和 execute for frame in video_stream: input_data preprocess(frame) acl.rt.memcpy(input_ptr, input_size, input_data.ctypes.data, input_size, acl.rt.MEMCPY_DEVICE_TO_DEVICE) acl.mdl.execute_async(...)4.2 多路视频流的并发架构在安防和工业质检场景经常需要同时处理多路视频流。Atlas 300V 24G 在内存上有天然优势但如何设计并发架构还是有讲究。我的方案是每路视频流分配一个独立的线程线程内部按顺序执行获取帧 - 预处理 - 推理 - 后处理。虽然 Atlas 300V 的推理是异步的但多路并发时要注意 CPU 资源竞争。YOLOv5s 的预处理和后处理在 CPU 上跑如果开了 8 路视频流每路的解码和缩放都占 CPU很容易打满 CPU 导致推理线程得不到调度。优化措施视频解码用硬件解码器DVPP不占用 CPU预处理只用 AIPP 和 DVPP 自带算子CPU 只做内存拷贝后处理用 numpy 向量化操作避免纯 Python 循环。按这个架构单卡 Atlas 300V 24G 实测能跑 8 路 1080p 视频流的 YOLOv5s 实时检测25 FPS 以上资源占用非常健康。还有一个容易忽略的点batch 和并发的取舍。如果你追求极致吞吐可以单次推理 batch 8 张图这样模型计算的并行效率会高一些如果你是视频流场景更建议 batch 1 多路并发因为视频帧到达时间不齐凑 batch 会引入额外延迟。两种方式的吞吐其实差别不大我自己测试下来在 5% 以内。4.3 常见报错排查速查表报错信息可能原因解决方案E10001: Failed to initialize acl驱动/固件未安装成功重新检查npu-smi info重装驱动E12002: Device not found卡没被识别或 PCIe 链路故障检查插槽、重插卡确认lspci能看到设备E10010: Unsupported data type输入 shape 或 dtype 与模型不匹配检查 input_shape 和预处理输出格式ATC model convert failedONNX 算子不支持检查 opset 版本用 onnxsim 简化图Malloc memory failed显卡内存不足或内存泄漏检查是否反复 malloc 未释放用内存池优化Output shape mismatch后处理 reshape 用了错误参数确认模型输出 shapeYOLOv5 三个头要分别处理acl.mdl.execute timeout推理异步未同步或卡忙检查 stream 同步逻辑确认没有死锁AIPP config erroraipp.cfg 参数不合法检查输入格式与 src_image_size 是否匹配4.4 我在部署中踩过的三个深坑坑一OpenCV 的 Resize 和 AIPP 的 Resize 结果不一致。这个问题非常隐蔽。我在 CPU 上用 OpenCV 的cv2.resize做预处理然后测试时发现检测框总是偏移几个像素。排查很久才意识到OpenCV 的插值算法默认是双线性插值而 AIPP 的 Resize 实现有自己的对齐方式两者的浮点精度存在细微差异叠加起来就造成了像素偏移。解决办法是预处理统一走 AIPP 或统一走 OpenCV不要在同一个 Pipeline 里混用两种方式。如果必须混用就要接受微小的对齐误差或者在输出检测框时加固定像素补偿。坑二模型输入是 RGB 还是 BGR 搞反了。PyTorch 训练时图像用的是 RGB 顺序但 OpenCV 读进来的是 BGR。很多人在 Deploy 时才踩到这个坑检测框乱跳、置信度极低。我在 AIPP 配置里专门加了csc_switch: true和rbuv_swap_switch: false确保数据从 BGR 转为 RGB 后再送入模型。坑三arm 架构服务器上编译依赖。如果你的服务器是鲲鹏 ARM 架构装 pyACL 时要注意 CANN 的 Python wheel 包分 x86_64 和 aarch64 两个版本装错会直接 import 失败。另外 ARM 上编译 onnx-simplifier 等工具特别慢建议直接用官方的预编译包不要自己源码编译。5. 模型量化与精度补偿5.1 为什么要做 INT8 量化Atlas 300V 24G 的 INT8 算力是 FP16 的两倍左右所以生产追求极致性能时量化是非做不可的。但量化不是无脑转换就行。我的做法是先用预训练好的模型做 PTQPost-Training Quantization校准用一小批有代表性的真实业务数据跑一遍 FP16 模型记录每层激活值的分布再根据分布选择合适的量化尺度。CANN 提供了 AMCTAscend Model Compression Toolkit来做量化。基本流程是准备 100-200 张代表性图片用 AMCT 脚本在 PyTorch 侧完成量化校准导出量化后的 ONNX重新用 ATC 转成 OM。校准集的选择很关键一定要贴近真实业务场景。我之前用 COCO 数据集做校准结果部署到工厂场景后因为输入图像的光线、材质和 COCO 差别太大检测精度暴跌。后来换成从真实产线上抽帧做校准集精度就恢复到了可以接受的范围。5.2 量化后精度掉点如何补偿量化掉点是常态关键是控制在可接受范围。我的补偿经验按优先级排列优先检查输入预处理是否完全一致很多时候掉点是因为归一化方式不同而不是量化本身造成的调低检测置信度阈值量化后模型输出的置信度普遍偏低偏保守从 0.25 调低到 0.15 往往能找回不少召回率校准集加大到 500 张让激活值分布估计更准确尝试不同的量化策略CANNT 里可以针对敏感层跳过量化或混用 FP16有些模型只量化前面几层就足够了。如果以上手段都不够那就回到 FP16 混合精度播放 20% 的性能换 2 个点的精度绝大多数项目是划算的。6. 后续可能场景扩展参考我在实际落地 Atlas 300V 24G 之后发现这块卡还挺百搭。除了 YOLO 检测还有几个场景值得扩展OCR 识别用 PaddleOCR 的检测模型加识别模型串联一个卡里同时加载两个模型内存完全够人脸识别/特征比对用 MobileFaceNet 或 ArcFace 做人脸特征提取24G 内存能缓存百万级特征向量库进行实时比对视频结构化把检测、分类、跟踪串成一条流水线在安防场景输出结构化日志。我个人在实际操作中的体会是Atlas 300V 24G 的定位很像一把瑞士军刀它不追求极致单卡算力但胜在内存大、功耗低、部署密度高。把模型转换和 AIPP 配置吃透之后多模型多任务的组合逻辑并不复杂重点在于前期的环境搭建和数据流设计。这些准备工作做到位后面扩展场景就是水到渠成的事。最后再分享一个小技巧如果你的应用是长期驻留服务进程建议在启动时做一次模型预热也就是用一张全黑图片跑一次推理把模型加载算子、分配内存这些一次性开销提前消耗掉避免在线请求第一个包的时候响应超时。虽然看起来是个小细节但做不做预热首查压测的 P99 延迟能差好几倍。
企业数字化 ERP 产品动态
相关推荐
Atlas 300V部署YOLOv5/YOLOv8实战:从环境搭建到推理优化 最近“atlas部署yolo”和“atlas 300v 24g是运算加速卡吗”这类问题,一下子热度上来了。我身边好几个做视频分析、工业质检、智慧巡检的朋友,几乎都在同一时间开始打听这款卡。正好过去几个月,我在一批Atlas设备上从零把YOLOv5和YOLOv8的推理… · 2026/9/25 19:28:41
Minimax H3接入ComfyUI:本地AI工作流的API调度实践 1. Minimax H3不是“另一个大模型”,而是本地AI工作流里的新式导演台最近在ComfyUI社区里,越来越多朋友开始问:“Minimax H3怎么接进本地ComfyUI?”——但这个问题本身就有陷阱。Minimax H3根本不是像Llama、Qwen或DeepSeek那样可… · 2026/9/25 19:28:35
Atlas 300V 24G部署YOLO实战:从ONNX转换到ACL推理调优全流程 做了好几年AI算法落地,我越来越确信一件事:推理卡和训练卡是两种完全不同的物种。最近团队接了个边缘侧目标检测项目,客户只给了一台国产服务器,里面有张Atlas 300V 24G,然后问了一句话:“这张卡能跑YOLO吗… · 2026/9/25 19:28:28
毕业论文AI率下不来?我实测了5款降AI工具,说点大实话 最近赶论文的同学应该都有同感:自己认真写的东西,过一遍检测系统直接飘红,AI疑似度动不动就五六成。说实话一开始我也懵,后来琢磨明白了——不是你的问题,是现在检测算法越来越敏感,有些表述稍微正式一点就… · 2026/9/25 19:57:09
企业连接海外社媒账号前,应核对哪些授权与安全信息? 企业把 TikTok、YouTube、Instagram 或 Facebook 账号连接到运营系统时,不能只确认"能不能连上"。更重要的是弄清:谁在授权、授权了什么、系统能做什么、数据保存到哪里、怎样取消,以及授权失效后如何处理。
下面这七组问题&#… · 2026/9/25 19:57:03
肌电信号分类数据集与代码:从预处理到SVM/CNN的完整流水线 简介:这份资源面向生物医学工程、康复医学与人机交互方向的学习者和研究者,围绕表面肌电信号(sEMG)分类任务,提供数据集与配套代码,帮助读者理解肌肉运动状态分析在医疗诊断、假肢控制与运动分析中的应用。… · 2026/9/25 19:56:32
Atlas 300V 24G推理加速卡部署YOLO实战:模型转换与ACL推理全解析 Atlas这个代号,在AI硬件圈子里这几年越来越常见。最近后台也老有人问“atlas 300v 24g是运算加速卡吗”“atlas部署yolo到底怎么搞”——我一开始接触Atlas 300V 24G的时候也有同样的疑惑,因为它外观和普通显卡摆在一起实在太像了,但本质上这… · 2026/9/25 19:56:20
GlusterFS 集群部署记录 文档 部署日期:2026-09-22
部署方式:基于项目脚本(GFS脚本-尹斌)自动化执行
软件版本:CentOS 7.9 GlusterFS 7.9一、集群拓扑主机名IP角色数据盘brick 路径状态node110.10.10.41存储节点/dev/sdb~sde(各10G&… · 2026/9/25 19:55:56
有哪些科研工具 科研工具涵盖软件与硬件两大类,按功能可分为文献管理、检索、数据分析、绘图、编程、AI 工具及实验仪器等 。 一、常用软件工具
1、文献管理: EndNote、Zotero、小绿鲸、NoteExpress、Mendeley,支持文献整理、引用生成和团队协作… · 2026/9/25 19:55:25
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37