T2000边缘计算模组开箱教程:从上电到跑通第一条NPU推理指令
简介这份T2000使用简易教程面向华为网管系统的初学者与一线运维人员帮助零基础用户快速掌握T2000的日常操作与业务排查方法。教程围绕网元管理器与以太网专线业务展开涵盖展开隐藏路径、确认端口业务状态、查看端口带宽、追踪以太口与业务开往方向、修改端口协商模式、查看光口告警以及以太口帧测试等核心场景并结合EFT、EFS板卡说明VCTRUNK与物理端口的对应关系配有大量截图辅助理解。资源包为1个docx文档大小约22.73MB图文并茂便于对照操作。目前已有511人学习适合需要快速上手T2000、排查专线故障或梳理业务走向的传输网管人员参考。1. T2000 使用简易教程从开箱到跑通第一条指令中间到底卡在哪第一次拿到 T2000 的人八成会经历同一个心理落差包装里只有一块巴掌大的板子、一根线、一张写着网址的卡片连个像样的说明书都没有。你把它插上电指示灯亮了然后呢打开电脑设备管理器里多出一个串口或者网络里多出一个陌生 IP但接下来该敲什么命令、装什么驱动、怎么确认它真的活着全靠自己摸索。这篇教程就是冲着这个「然后呢」来的。T2000 这类边缘计算模组本质是一台跑着精简 Linux 的小电脑算力在几 TOPS 到几十 TOPS 之间常见用途是本地推理、视频结构化、工业网关协议转换。它不像树莓派那样有庞大的社区教程也不像服务器那样有完整的带外管理很多信息散落在零散的文档片段里。我写这篇东西是想把「插上电到跑通第一条推理指令」这条路径上的每一步都摊开讲清楚包括那些文档里不会写、但一定会让你卡住的细节。适合刚拿到设备的新手也适合已经跑通基础功能、想搞清楚参数边界的老手。2. 上电之前先把这三件事定下来供电、散热、网络2.1 供电选错后面全是玄学问题T2000 的供电规格通常标称 12V DC但实际电流需求波动很大。空载时可能只有 0.3A一旦 NPU 开始跑推理瞬时电流能冲到 2A 以上。如果你用一个标称 12V/1A 的普通适配器轻则推理到一半设备重启重则反复掉电导致文件系统损坏。我一般会直接上 12V/3A 的电源留足余量。另一个容易被忽略的点是电源接口的极性。不同批次的 T2000 可能用 DC 圆头或端子台圆头又分内正外负和内负外正。接反了不会立刻烧但设备会处于一种「灯亮着但串口无输出」的诡异状态。拿到设备第一件事用万用表量一下适配器输出极性和板子丝印是否一致这个动作花三十秒能省掉后面两小时的排查。提示如果你用 USB-C 供电注意 PD 协议协商需要时间部分 T2000 在协商完成前会反复重启表现为串口日志刷到一半就断。建议先用 DC 供电完成首次配置。2.2 散热不是可选项是稳定性的前提T2000 的 SoC 在满载推理时结温可以轻松突破 80°C。裸板不加散热片跑一个 ResNet-50 的量化模型大概三到五分钟就会触发降频推理延迟从 20ms 跳到 80ms 以上。更麻烦的是降频是动态的你看到的性能数据会忽高忽低很容易误判成模型或代码有问题。我的做法是如果设备有官方散热外壳直接用如果没有至少贴一块 20x20x6mm 的铝散热片有条件再加一个 5V 小风扇对着吹。判断散热是否到位不用红外测温枪跑推理时执行cat /sys/class/thermal/thermal_zone0/temp数值稳定在 60000 以下即 60°C就算合格。超过 75000 就要考虑加强散热了。2.3 网络配置有线优先静态 IP 省心T2000 通常有一个千兆网口和一个 WiFi 模组。首次配置强烈建议走有线因为 WiFi 驱动在部分精简系统里需要额外固件而且信号不稳会导致 SSH 断连让你误以为设备挂了。网络配置有两种常见方式一是设备默认开 DHCP你从路由器后台找它的 IP二是设备默认静态 IP比如 192.168.1.100你把自己的电脑改成同网段。我一般会先试 DHCP连上后用ip addr确认地址然后立刻改成静态 IP避免路由器重新分配导致 IP 变化。改静态 IP 的命令因系统而异如果是 systemd-networkd编辑/etc/systemd/network/10-eth0.network# 编辑网络配置文件设置静态 IP sudo nano /etc/systemd/network/10-eth0.network # 文件内容示例 [Match] Nameeth0 [Network] Address192.168.1.100/24 Gateway192.168.1.1 DNS192.168.1.1改完后sudo systemctl restart systemd-networkd生效。注意 Address 后面的 /24 不能漏否则子网掩码不对网关可能不通。如果你用的是 NetworkManager命令换成nmcli那一套逻辑一样。3. 首次登录与系统初始化串口、SSH 和必做的五条命令3.1 串口登录最后的救命通道不管网络通不通串口一定是能用的。T2000 的调试串口通常是 3.3V TTL 电平波特率 115200。你需要一个 USB 转 TTL 模块TX 接板子 RXRX 接板子 TXGND 对接。注意不要接 VCC板子自己供电。接好后Linux 下用minicom或screenWindows 下用 PuTTY 或 MobaXterm。以 screen 为例# 查看串口设备名通常是 ttyUSB0 或 ttyACM0 ls /dev/ttyUSB* # 用 screen 连接波特率 115200 sudo screen /dev/ttyUSB0 115200 # 退出 screen 的快捷键是 CtrlA 然后按 K再按 Y 确认连接成功后按回车应该能看到登录提示。默认用户名和密码一般在设备标签或文档里常见的是 root/root 或 admin/admin。如果按回车没反应检查 TX/RX 是否接反这是血泪经验里排第一位的翻车点。3.2 SSH 登录与密钥配置网络通了之后SSH 是日常操作的主要方式。首次登录用密码登录后第一件事是配置密钥登录省得每次输密码也避免密码被暴力破解。# 在本地电脑生成密钥对如果已有可跳过 ssh-keygen -t ed25519 -C t2000-access # 把公钥复制到设备假设设备 IP 是 192.168.1.100 ssh-copy-id root192.168.1.100 # 测试免密登录 ssh root192.168.1.100如果ssh-copy-id不可用手动把本地~/.ssh/id_ed25519.pub的内容追加到设备的~/.ssh/authorized_keys里。注意权限.ssh目录要是 700authorized_keys要是 600权限不对 SSH 会拒绝密钥登录而且日志里只写「Permission denied」不告诉你具体原因这个坑我踩过不止一次。3.3 系统初始化五条命令登录后别急着跑模型先把系统状态摸清楚。下面五条命令我每台新设备都会跑一遍# 1. 查看系统版本和内核 uname -a cat /etc/os-release # 2. 查看 CPU 和内存 cat /proc/cpuinfo | grep model name | head -1 free -h # 3. 查看存储空间确认根分区没满 df -h # 4. 查看温度确认散热正常 cat /sys/class/thermal/thermal_zone0/temp # 5. 查看网络和监听端口 ip addr ss -tlnp这五条命令的输出能告诉你很多信息内核版本决定了驱动兼容性内存大小决定了能跑多大的模型存储空间决定了你能放多少数据温度决定了性能是否稳定监听端口决定了有没有意外暴露的服务。我一般会把输出存一份到本地后面出问题时对比用。注意如果df -h显示根分区使用率超过 80%先清理日志和缓存否则后面装推理框架时可能因为空间不足失败而且失败信息往往指向一个不相关的错误。4. 跑通第一条推理指令环境准备与最小可复现示例4.1 推理框架选型先确认官方支持哪个T2000 的 NPU 通常需要专用推理框架常见的是厂商基于 TensorFlow Lite 或 ONNX Runtime 定制的版本也可能提供 RKNN、昇腾 CANN 这类专用工具链。选型第一步不是看哪个流行而是看设备出厂系统里预装了哪个。# 查找预装的推理相关工具和库 which rknn_server 2/dev/null pip list 2/dev/null | grep -i -E rknn|onnx|tflite|torch ls /usr/lib/ | grep -i -E rknn|npu|infer如果预装了 RKNN 工具链就用 RKNN如果预装了 ONNX Runtime就用 ONNX。不要试图在 T2000 上从源码编译 PyTorch交叉编译环境配置能吃掉你一整天而且编译出来的版本未必能用 NPU 加速。常见做法是在 PC 上把模型转成设备支持的格式再推到设备上跑。4.2 模型转换在 PC 上完成别在设备上折腾以 ONNX 模型转 RKNN 为例转换脚本在 PC 上跑需要安装 rknn-toolkit2。转换的核心是量化配置这一步直接决定推理速度和精度。# convert_to_rknn.py在 PC 上运行 from rknn.api import RKNN # 创建 RKNN 对象 rknn RKNN(verboseTrue) # 配置模型输入mean_values 和 std_values 要和训练时一致 rknn.config( mean_values[[123.675, 116.28, 103.53]], std_values[[58.395, 57.12, 57.375]], target_platformrk3588 # 根据实际 T2000 芯片填写 ) # 加载 ONNX 模型 ret rknn.load_onnx(modelmodel.onnx) if ret ! 0: print(加载模型失败) exit(ret) # 构建模型do_quantizationTrue 开启量化 ret rknn.build(do_quantizationTrue, datasetdataset.txt) if ret ! 0: print(构建失败) exit(ret) # 导出 RKNN 模型 ret rknn.export_rknn(model.rknn) if ret ! 0: print(导出失败) exit(ret) rknn.release()这里有几个参数必须说清楚。mean_values和std_values是预处理参数如果和训练时不一致精度会掉得莫名其妙你以为是量化问题其实是归一化错了。dataset.txt是量化校准集里面是几十到几百张代表性图片的路径每行一个。校准集不具代表性量化后的模型在真实场景就会翻车。target_platform必须和 T2000 的实际芯片匹配填错了转换能过但设备上加载会报错。4.3 设备端推理最小可复现示例把转换好的model.rknn和一张测试图片推到设备上跑推理# infer_on_t2000.py在设备上运行 import numpy as np from rknnlite.api import RKNNLite import cv2 # 初始化 RKNN Lite这是设备端的轻量运行时 rknn RKNNLite() # 加载模型 ret rknn.load_rknn(model.rknn) if ret ! 0: print(加载 RKNN 模型失败) exit(ret) # 初始化运行时指定 NPU 核心 ret rknn.init_runtime(core_maskRKNNLite.NPU_CORE_0) if ret ! 0: print(初始化运行时失败) exit(ret) # 读取图片并预处理 img cv2.imread(test.jpg) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img cv2.resize(img, (224, 224)) img np.expand_dims(img, axis0) # 推理 outputs rknn.inference(inputs[img]) # 输出结果形状和前几个值 print(输出形状:, outputs[0].shape) print(前五个值:, outputs[0].flatten()[:5]) # 释放资源 rknn.release()这段代码里core_mask指定用哪个 NPU 核心。T2000 如果有多个核心可以设成NPU_CORE_0_1_2来并行但要注意多核心推理需要模型支持不是所有模型都能自动拆分。rknn.inference的输入是一个列表即使只有一个输入也要用列表包起来。输出是一个列表取outputs[0]拿第一个输出张量。跑通这一步你会看到输出形状和数值。如果形状不对检查模型转换时的输入尺寸如果数值全是 NaN检查预处理是否和转换时一致如果报错「init_runtime failed」八成是 NPU 驱动没加载执行lsmod | grep npu确认。5. 避坑与排查五个让新手卡一整天的典型问题5.1 串口有输出但无法输入现象screen 或 minicom 里能看到启动日志但敲键盘没反应回车也没用。原因TX 和 RX 接反了或者串口模块的电平不对。T2000 调试串口是 3.3V TTL如果你用的是 RS232 电平的模块信号电平不匹配能收到但发不出去。解决交换 TX 和 RX 接线确认串口模块是 3.3V 而非 5V 或 RS232。用万用表量模块 TX 引脚空闲时的电压应该是 3.3V 左右。5.2 SSH 连接被拒绝但 ping 得通现象ping 192.168.1.100正常但ssh root192.168.1.100报「Connection refused」。原因SSH 服务没启动或者监听端口不是 22。部分精简系统默认不开 SSH需要手动启动。解决通过串口登录执行systemctl status sshd查看状态systemctl start sshd启动。如果端口被改过ss -tlnp | grep ssh看实际端口。5.3 推理结果和 PC 上不一致现象同一个模型PC 上跑出来的分类结果正确T2000 上跑出来完全不对。原因预处理不一致或者量化校准集不具代表性导致精度损失过大。解决先确认 mean/std 和训练时一致再确认输入图片的通道顺序RGB vs BGR。如果这两项都对把量化关掉do_quantizationFalse重新转换跑一遍看结果是否恢复。如果关掉量化就对了说明校准集需要补充更多真实场景图片。5.4 设备跑一段时间后自动重启现象推理跑几分钟后设备重启串口日志显示内核 panic 或直接断电。原因供电不足或散热触发保护。供电不足占七成以上。解决换 12V/3A 以上的电源用万用表监测推理时电压是否跌到 11V 以下。如果是散热问题温度会先冲到 90°C 以上再重启加散热片和风扇。5.5 模型加载报「invalid model」现象load_rknn返回非零提示模型无效。原因模型转换时的target_platform和设备实际芯片不匹配或者转换工具版本和设备端运行时版本不兼容。解决确认转换时填的芯片型号和设备一致。如果型号对检查工具链版本PC 上pip show rknn-toolkit2看版本设备上rknn_server的版本要匹配。版本不匹配时要么升级设备端运行时要么降级 PC 端工具链我一般选择后者因为升级设备端运行时可能牵扯驱动。6. 进阶技巧用 Python 脚本批量验证与性能基线跑通单张图片推理之后下一步是建立性能基线。你需要知道这个模型在 T2000 上的真实延迟和吞吐才能判断后面优化有没有效果。我一般会写一个批量验证脚本跑一百次推理统计平均延迟、P99 延迟和内存占用。# benchmark.py在设备上运行 import time import numpy as np from rknnlite.api import RKNNLite rknn RKNNLite() rknn.load_rknn(model.rknn) rknn.init_runtime(core_maskRKNNLite.NPU_CORE_0) # 构造随机输入形状要和模型匹配 input_data np.random.rand(1, 224, 224, 3).astype(np.float32) # 预热 10 次让 NPU 进入稳定状态 for _ in range(10): rknn.inference(inputs[input_data]) # 正式测 100 次 latencies [] for _ in range(100): start time.perf_counter() rknn.inference(inputs[input_data]) end time.perf_counter() latencies.append((end - start) * 1000) # 转毫秒 latencies np.array(latencies) print(f平均延迟: {latencies.mean():.2f} ms) print(fP50 延迟: {np.percentile(latencies, 50):.2f} ms) print(fP99 延迟: {np.percentile(latencies, 99):.2f} ms) print(f最小延迟: {latencies.min():.2f} ms) print(f最大延迟: {latencies.max():.2f} ms) rknn.release()这个脚本的关键在于预热。NPU 首次推理会做频率爬升和缓存加载前几次延迟偏高不预热直接测平均值会虚高。预热十次之后数据才反映真实性能。P99 延迟比平均延迟更重要它决定了你的系统在极端情况下的响应上限。如果 P99 是平均值的两倍以上说明有资源竞争或散热降频需要进一步排查。另一个技巧是监控推理时的 CPU 和 NPU 占用。在另一个终端跑top -d 1和cat /sys/kernel/debug/rknpu/load路径因平台而异能看到推理时 CPU 是否成为瓶颈。如果 CPU 占用很高而 NPU 占用很低说明数据预处理在 CPU 上耗时太多可以考虑用硬件加速的预处理或者把预处理也放到 NPU 上。我自己的习惯是每换一个模型或调整一次参数都跑一遍这个基线脚本把结果记在一个表格里。时间长了你就能看出哪些优化真正有效哪些只是心理安慰。这个习惯帮我省了很多「感觉快了但说不清哪里快」的纠结。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Unity中D*Lite动态寻路实战:增量式重规划优化指南

Unity中D*Lite动态寻路实战:增量式重规划优化指南

1. 这不是普通寻路——D*Lite在Unity中解决的是动态环境下的实时重规划问题“DLite Unity项目主要源码”这个标题乍看平平无奇,像是一份被随手打上标签的代码仓库快照。但如果你在某次开发中遇到过这样的场景:一个机器人在未知地图中边探索边移动&#x…

2026/10/14 15:57:02 阅读更多 →
Vim配置Python和C++开发环境:LSP插件实战指南

Vim配置Python和C++开发环境:LSP插件实战指南

1. 为什么现在还要花时间啃 Vim?——一个老手的真实观察我第一次在某高校实验室的服务器上看到导师用 Vim 十分钟内修完一个 C 模板元编程导致的编译错误时,手里的 VS Code 窗口正卡在“正在分析 127 个头文件依赖”上。那不是炫技,是他在调试…

2026/10/14 15:57:02 阅读更多 →
51单片机驱动MAX30205高精度体温传感器实战

51单片机驱动MAX30205高精度体温传感器实战

简介:这份资源面向使用STC8系列51单片机进行传感器开发的初学者与工程师,解决如何用硬件I2C驱动MAX30205高精度体温传感器并读取温度数据的问题。压缩包共33个文件,约134KB,包含5个c源文件、6个h头文件、6个obj与6个lst编译中间文…

2026/10/14 15:56:01 阅读更多 →

最新新闻

AI Agent状态清理:超时重试背后的系统性风险与四维治理

AI Agent状态清理:超时重试背后的系统性风险与四维治理

1. 这不是超时和重试的问题,是状态管理的系统性溃败“给 AI Agent 加超时和重试后,我才发现真正的坑在状态清理”——这句话刚在内部技术群刷出来时,我正盯着一个跑了37分钟、卡在waiting_for_tool_execution状态、内存占用飙升到4.2GB却毫无…

2026/10/14 16:41:53 阅读更多 →
嵌入式Qt记事本开发全链路:从交叉编译到中文文件IO

嵌入式Qt记事本开发全链路:从交叉编译到中文文件IO

简介:这是一份基于Qt6开发的跨平台记事本项目源码,面向嵌入式与桌面应用开发初学者及Qt进阶学习者,聚焦GUI界面构建、文件编码处理与轻量级文本编辑功能实现。项目完整呈现了现代C在Qt框架下的典型工程实践,涵盖主窗口&#xff08…

2026/10/14 16:41:53 阅读更多 →
计算机系统概论第一章答案精讲:ISA、微架构与算法性质

计算机系统概论第一章答案精讲:ISA、微架构与算法性质

简介:计算机系统概论(原书第二版)第一章习题答案以PDF形式提供,面向计算机专业学生、考研读者和自学入门者,用于对照教材习题检验对计算机系统基础概念的掌握。内容选自原书附录的精选解答,覆盖冯诺依曼通用…

2026/10/14 16:41:53 阅读更多 →
远视储备与近视防控:从原理到实操的家长指南

远视储备与近视防控:从原理到实操的家长指南

1. 远视储备不是“储备”,而是一笔会不断消耗的视力存款1. 远视储备不是“储备”,而是一笔会不断消耗的视力存款1.1 远视储备到底是什么很多家长第一次听到“远视储备”这个词,是在幼儿园体检或者眼科门诊的报告单上。医生指着上面的数字说&a…

2026/10/14 16:41:53 阅读更多 →
Python数据挖掘实战:K均值聚类从原理到应用

Python数据挖掘实战:K均值聚类从原理到应用

1. 从一个真实需求说起:为什么K均值聚类值得你花时间搞懂做数据挖掘这些年,我越来越觉得,K均值聚类是那种“看起来简单、用起来真香、但踩坑也真不少”的算法。很多刚入门的朋友一听到“无监督学习”四个字就头大,觉得没有标签怎么…

2026/10/14 16:41:53 阅读更多 →
MinGW-w64离线安装包:断网Windows下C/C++工具链部署指南

MinGW-w64离线安装包:断网Windows下C/C++工具链部署指南

简介:MinGW-w64是为64位Windows系统打造的GCC工具链离线安装包,面向需要在Windows环境下学习或开展C语言开发的程序员。压缩包约2000个文件、133.98MB,主要由h头文件、Python脚本、a静态库、pyc编译文件、exe可执行程序、dll动态库及少量c源文…

2026/10/14 16:40:52 阅读更多 →

日新闻

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/14 16:30:29 阅读更多 →
影刀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 阅读更多 →