news 2026/10/5 6:08:21

Qwen3-VL、Qwen3-Next、Qwen3.5架构全拆解:多模态模型选型与部署实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Qwen3-VL、Qwen3-Next、Qwen3.5架构全拆解:多模态模型选型与部署实战

做多模态大模型的朋友,最近应该都被Qwen系列的三条产品线刷屏了。Qwen3-VL、Qwen3-Next、Qwen3.5,名字看着接近,实际是三条完全不同的技术路线:一条是多模态感知基座,一条是超高性价比的纯文本MoE,还有一条则是把视觉、语音、代码、Agent能力揉在一起的融合体。我花了两周时间把这几个模型的架构、训练策略和落地方式拆了一遍,这篇就把最关键的东西整理出来。

先说结论:如果你只做图像理解或视频理解,Qwen3-VL是唯一解;如果你要的是极低推理成本下的文本能力,Qwen3-Next是最划算的选项;如果你在做Agent类应用,需要模型同时处理多模态输入、调用工具、写代码,Qwen3.5那套融合架构才是真正值得研究的对象。下面从架构设计的底层逻辑开始拆。

1. 三个模型各是什么:定位与架构演进主线

1.1 三者定位:多模态基座、高性价比MoE与全能融合体

要理解这三个模型,先要搞清楚它们解决的问题完全不同。

Qwen3-VL是Qwen3系列的多模态版本,核心任务是把视觉信息(图像、视频、OCR、文档)和文本信息统一到一个模型里。它的前身是Qwen2-VL,所以架构上延续了视觉编码器加连接器加大语言模型主干的经典三段式,但在视觉Token压缩、动态分辨率、视频时序建模上做了大幅升级。适合做图像理解、视频理解、文档解析、物体检测这类任务。

Qwen3-Next则是一个非常有意思的尝试。它本质上是一个MoE(混合专家)架构的纯文本模型,主打的是用少量的激活参数达到接近大模型的性能。它的架构特点是每个Token只激活一部分专家,推理时计算量远小于同体量的稠密模型。所以它的定位非常明确:在GPU资源有限、对延迟敏感的生产环境中,用最低成本跑出尽可能好的文本生成效果。

Qwen3.5则是最新的一条产品线,它不再区分纯文本和多模态,而是把视觉、语音、文本、代码、工具调用这些能力统一到一个模型里。从架构上看,它更像是Qwen3-VL的进化版加上Qwen3-Next的MoE效率思路,再整合了Agent工作流的支持。这个模型的设计目标很直白:让一个模型能干所有事,而不是像以前那样,视觉用一个模型、文本用一个模型、工具调用再拼一个框架。

1.2 架构演进的三条主线

把三代模型的架构放在一起看,能发现三条特别清晰的演进主线。

第一条线是模态融合的深度变化。Qwen3-VL时代,视觉和文本是两套独立的编码路径,靠连接器做对齐;到了Qwen3.5,视觉Token和文本Token在输入层就已经统一,进入主干后走同一条Transformer路径。这个变化直接带来了两个好处:一是跨模态的注意力交互更充分,模型在处理“图里的文字加图表加语音说明”这类复合输入时不会出现信息丢失;二是可以复用主干网络的全量参数,不需要为每个模态单独训练一套专家。

第二条线是效率优化。Qwen3-Next率先把MoE结构引入,每个Token只激活部分专家,这直接降低了推理时的浮点运算量。Qwen3.5继承了这一思路,在视觉Token的压缩上也更激进,比如对高分辨率图像做了更精细的Token裁剪,让模型在保持理解能力的前提下减少计算量。

第三条线是训练目标的变化。Qwen3-VL主打的是感知能力,强调“看得懂”;Qwen3.5则强调“能行动”,训练目标从理解任务扩展到工具调用、代码执行、多轮交互。这意味着Qwen3.5的架构设计从一开始就考虑了Agent场景,比如在训练数据里加入了大量的工具调用轨迹和代码执行结果。

2. 核心架构细节:视觉编码、模态对齐与主干网络

2.1 视觉编码器与分辨率适配

多模态模型的第一关是视觉编码。Qwen3-VL没有采用最粗暴的方式,也就是把整张图缩放到固定尺寸再丢给视觉编码器,而是用了动态分辨率策略。

具体来说,它会把输入图像划分为多个patch,每个patch的边长是固定的(通常是14或16像素),然后根据图像的实际宽高比,将patch排列成不同的网格。比如一张1920x1080的图,会被切成138x78个patch左右的网格,而不是强行压成正方形。这样做的好处是保留了图像的原始纹理和细节,不会因为缩放导致小物体模糊或者文字歪曲。

视觉编码器本身用的是ViT(Vision Transformer)结构,这个选择背后有清晰的逻辑:ViT的输出天然是序列化的patch embedding,可以直接和文本序列拼接,不需要额外的二维空间编码;相比之下,CNN类的编码器输出是特征图,还得先展平再映射,中间多了一道转换,信息损失更大。ViT还能利用预训练权重做初始化,大规模训练时收敛更快。

到了Qwen3.5,视觉编码的粒度进一步细化。它在ViT后面加了一个可学习的降采样模块,不是简单地取前N个patch,而是根据图像内容的复杂程度动态决定保留多少视觉Token。简单来说,一张纯色背景的文字截图,可能只需要几十个视觉Token就能表达;但一张内容丰富、包含多个物体的场景图,则可能需要几百个Token。这个“按需分配Token”的机制,直接影响了推理时显存的占用,也是Qwen3.5在长视频理解上能跑起来的关键。

2.2 连接器设计与多模态对齐

视觉编码器输出的是一堆patch embedding,文本序列也是一堆token embedding,但两者并不在一个语义空间里。连接器就是用来把视觉向量“翻译”成语言模型能理解的向量表达。

Qwen3-VL用的连接器是多层交叉注意力(cross-attention)结构。视觉Token作为query,文本Token作为key和value,通过几层注意力计算把视觉信息加权到文本侧。这种做法比早期模型直接用一个线性层做映射要精细得多,因为线性层只能做逐点变换,而交叉注意力可以建模视觉Token之间的上下文关系,等于在做一次信息筛选——保留对当前任务有用的视觉信息,忽略无关的背景噪声。

Qwen3.5则把这一步做得更极致。它在连接器阶段引入了一个轻量级的Q-Former变体,通过一组可学习的query向量来压缩视觉信息。这组query的数量远少于原始视觉Token数量,但通过注意力机制可以充分聚合整个图像的信息。这样一来,进到主干网络的视觉信息已经是高度提炼的“摘要”,而不是一堆冗余的patch。代价是训练时需要对Q-Former做额外的预训练,让query向量学会提取有效视觉特征;好处是推理时显存占用降低,在高分辨率图像上尤其明显。

2.3 主干网络与MoE效率设计

再看最核心的主干网络。Qwen3-VL的文本主干沿用了Qwen系列的标准Transformer decoder结构,层数通常在28到64层之间,隐藏层维度在2048到8192之间。这块的架构本身没有太多新东西,真正的重点是训练策略——它用了大规模的中英文混合多模态数据做预训练,文本主干在初始化时直接复用纯文本Qwen模型权重,视觉部分则从头开始训练。两阶段的训练策略保证了视觉模块和文本模块都能充分收敛,避免相互干扰。

Qwen3-Next的主干网络则完全是另一个思路。它采用了MoE架构,把Transformer的前馈网络(FFN)层替换成多个并行的专家网络,每个Token只激活其中少数几个专家。举个例子:如果模型总共有64个专家,每个Token只路由到其中的6个,那么单个Token的计算量就相当于稠密模型的6/64,推理时省下的计算量是数量级的。

这种架构设计最考验的是路由机制。Qwen3-Next用的路由策略是Top-k门控加负载均衡正则化。Top-k门控就是让每个Token选择得分最高的k个专家;负载均衡正则化则是为了防止“富者愈富”——如果所有Token都倾向于选择某个专家,这个专家就会过载,而其他专家得不到充分的训练。做法是在训练损失里加一项惩罚项,鼓励Token均匀分布到各个专家上。

从实际效果看,Qwen3-Next能以大约三分之一的激活参数量达到接近于稠密大模型的文本生成质量。它的定位场景非常明确:批量文本生成、知识库问答、日志分析这类对延迟和成本敏感的任务。如果你跑的是纯文本任务且没有复杂的多模态需求,从Qwen3-Next入手是性价比最高的选择。

Qwen3.5的主干网络则是融合了以上两者的特点:主体是稠密Transformer,但在中间层引入了少量稀疏专家来处理高难度推理任务。这个设计的思路是:简单任务走稠密路径,速度快;复杂任务再激活专家路径,能力强。实测下来,这种混合设计在代码生成和数学推理上的提升比较明显,而在通用对话场景下,推理速度并不比纯稠密架构慢多少。

2.4 模态对齐与训练阶段

多模态模型的训练不是一步到位的,而是分阶段进行。这里有一个非常关键的概念:多模态对齐。它解决的是“图像中的猫”和文本中的“猫”如何映射到同一个语义空间的问题。

Qwen3-VL采用的训练流程是典型的四阶段。第一阶段是视觉编码器预训练——用海量图片文本对比学习让视觉编码器学会识别物体、场景、文字;第二阶段是连接器训练——冻结视觉编码器和文本主干的参数,只训练连接器,让视觉向量和文本向量对齐;第三阶段是多模态指令微调——把视觉模块和文本模块解冻,用图文对话数据做全量训练,让模型学会在对话中理解图像内容;第四阶段是特定任务优化——用更高质量的数据做强化学习对齐,提升模型的遵循能力和安全性。

这个流程的精髓在于每个阶段都有明确的目标,并且通过冻结参数来控制训练的层级。前两个阶段相当于让模型先学会“看”,后两个阶段相当于让模型学会“看的同时想和说”。如果一上来就解冻全部参数训练,模型很容易出现灾难性遗忘——学会新任务的同时忘了旧任务,输出质量会很不稳定。

Qwen3.5在此基础上增加了一个额外的“工具对齐”阶段。在这个阶段,训练数据里不仅有多模态对话,还混入了工具调用记录、API返回结果、代码执行输出。模型需要学会根据用户指令决定是否调用工具、调用哪个工具、如何把工具返回结果组织成自然语言回答。这也是Qwen3.5能作为Agent基座模型的根本原因——它的训练目标里天然包含了“行动”这一环。

3. 实操落地:微调、推理与部署要点

3.1 物体检测微调:最小操作与数据准备

我把前阵子做的一个实际案例放出来:用Qwen3-VL微调一个物体检测模型,目标是识别流水线上的特定工件型号。

第一步是数据准备。我采集了约2000张带有标注框的工件图像,标注格式用的是COCO的JSON格式。这里要注意,Qwen3-VL的微调数据格式与纯文本模型不同。单轮对话的数据结构大致是:用户消息中包含图像占位符和文本指令,助手消息中包含模型应输出的检测结果。检测结果的输出格式需要与模型的预训练指令保持一致,否则模型会迷茫。

训练时最关键的超参数是学习率和LoRA的秩。我的经验是:从0.00005开始,如果loss震荡就降一个数量级;LoRA的秩设成64比较稳妥,太高容易过拟合,太低则学不到足够的知识。需要注意的是,视觉效果相对文本更敏感,学习率大了会出现灾难性遗忘,很多人类高质量参数全丢了,表现为模型开始输出乱码或者重复文本。

我还踩过一个坑:训练数据中超过60%的图像是小尺寸的物体(比如螺栓、垫圈),微调出来的模型对于大物体检测效果正常,但对于小物体经常漏检。后来分析原因,是视觉编码器在动态分辨率策略下会优先保留大物体相关的小块区域,小物体本来token数量就少。解决方式是做了数据增强,把小目标复制粘贴到背景中扩充样本,效果立竿见影。

3.2 推理资源估算与显存优化

跑多模态模型最头疼的问题是显存。以Qwen3-VL-7B为例,模型权重大约14GB(FP16),如果输入一张1920x1080的图片,会产生超过1200个视觉Token,这些Token在自注意力计算中的显存开销不可忽略。

实测来看,一张1080p的图加一段512字的文本,推理时的峰值显存在24GB左右。这个数字对于单卡A100(80GB)毫无压力,但对于消费级的RTX 4090(24GB)就比较紧张。如果需要在4090上跑,必须开启量化。我试过用AWQ 4-bit量化,模型权重从14GB降到约4GB,虽然显存压力大减,但检测精度下降了约1.5个百分点。对于精度敏感的任务,建议至少使用8-bit量化。

还有一个非常实用的技巧:动态Token裁剪。Qwen3-VL在推理时允许通过API参数控制视觉Token的上限。实际操作中,我对长宽比异常的图像(比如超宽全景图)先做一次长边缩放到1080,再让模型处理,这样能避免视觉Token数量失控。文本生成侧出现极端长回复时,模型也会被显存打爆,这时可以限制max_new_tokens值,明显降低显存抖动。

选卡方面,推理场景建议优先考虑H20或者L40S,它们的大显存加上NVLink高速互联非常适合多模态模型的推理负载。如果没有这类卡,消费级4090可以通过量化方案跑7B或8B级模型,性能可以接受。

3.3 分布式部署与并行策略

当模型规模上到72B级别,单卡肯定是放不下的,这时就需要分布式推理。

常见做法是张量并行(Tensor Parallelism)加流水线并行(Pipeline Parallelism)混合使用。张量并行是把一个Transformer层的权重切分到多张卡上,每张卡计算一部分,再通过all-reduce汇总结果。流水线并行则是把模型的层切分成多个阶段,每个阶段放在一张卡上,数据像流水线一样依次经过每个阶段。

实际部署中使用DeepSpeed或vLLM框架可以极大简化这一过程。以vLLM为例,只需要指定--tensor-parallel-size 8,框架会自动完成注意力头和FFN权重的切分。有一个细节容易被忽略:多卡环境下,卡间的通信带宽非常重要。我做过一次对比,用PCIe 4.0的4卡机器跑72B模型,QPS只有NVLink互联的4卡A100的60%左右。所以如果预算允许,优先选择支持NVLink的卡。

Qwen3-Next的MoE架构在推理时会面临一个额外的挑战:因为每个Token只激活部分专家,专家分布在多张卡上时,Token需要在不同卡之间传递,这就产生了额外的通信开销。解决思路是利用experts parallel(专家并行)加适当的负载均衡策略,确保每个专家收到的Token数量大致相当。实测下来,vLLM对Qwen3-Next这类MoE模型的调度已经优化得很成熟,如果你自己写推理服务,一定要在调度策略上多花时间。

4. 常见问题与排查技巧实录

4.1 视觉过拟合:现象、原因与对策

视觉过拟合是我在微调Qwen3-VL时遇到最多的一个问题。现象是训练集上的loss下降很快、准确率很高,但一到验证集准确率大幅跳水。后来排查下来,主要原因有三个。

第一是训练数据太少。视觉模型的参数量远大于文本模型的可学习参数,同样需要更多数据来收敛。我试过只用500张图做微调,结果验证集准确率只有训练集的一半不到。后来把数据加到2500张才算勉强稳定。

第二是数据分布不均衡。如果训练集里80%都是同一类物体、同一种背景,模型就会在背景和物体之间建立虚假关联。比如检测汽车时,训练集里的汽车都出现在公路上,模型可能就把“公路”当成了判断汽车的线索之一。解决方式是扩充背景多样性,或者用随机裁剪做数据增强,强制模型关注目标本身而不是环境。

第三是学习率设置不当。多模态模型比纯文本模型对学习率更敏感。我当时把学习率调到0.0003,训练到第3个epoch就开始出现验证集loss反弹。把学习率降回0.00005之后,问题立刻缓解。建议从极小的学习率开始,逐步增大到一个合适区间后,再用余弦退火慢慢降低。

4.2 显存不足:定位瓶颈与针对性优化

显存溢出是最常见、最让新手头大的问题。很多人一报OOM就以为显存不够,直接去换更大的卡,其实多数情况下是某个环节的显存分配不合理。

我从经验中总结了一套排查流程,按照“激活显存 → KV Cache → 权重”的顺序排查。第一步,看是不是输入过长导致激活值过多。一张高分辨率图产生的视觉Token数可能轻松超过1000个,这会直接推高激活值的显存占用。解决办法是动态分辨率裁剪、限制图片长边尺寸、控制文本长度。第二步,看KV Cache是否过大。如果图片和文本的序列都很长,KV Cache会占用大量显存。解决办法是用PagedAttention机制按需分配缓存,或者提高gpu_memory_utilization这个参数让框架更积极地利用空闲显存。第三步才排查权重显存,如果模型本身就是72B甚至更大,才需要量化或分布式部署。

还有一个容易被忽略的隐性显存占用来自视觉编码器和文本编码器的中间特征存储。在多模态模型里,视觉编码器处理一张大图的特征图会占掉不少显存。Qwen3.5在推理时会默认开启一个特征释放机制,但Qwen3-VL没有这个功能,所以用Qwen3-VL做推理时,如果同时处理多张图,需要手动控制并发数。

4.3 微调数据格式与Token策略避坑

微调多模态模型还有一个容易出问题的点:数据格式。每个模型对自己的输入输出格式都有严格定义,用错一个标签,Loss可能都不下降。

以Qwen3-VL为例,它的微调数据格式要求用户消息里先用<|vision_start|>和<|vision_end|>把图像占位符包起来,然后跟文本指令,助手消息直接输出答案。如果用早期版本的格式规范套新版本模型,很可能模型完全学不到东西。

另外一个隐藏很深的问题是Token长度控制。多模态微调时,如果输入的视觉Token数量过多(比如超过模型设置的上限),训练过程会自动截断。截断后的视觉信息可能只包含了图中一部分内容,导致微调出来的模型对某些方向的检测有偏好。我遇到过的一个案例是:微调火灾烟雾检测模型时,训练集图片大多是横向构图,部分竖向构图图片在截断后丢失了顶部信息,导致模型对画面顶部的烟雾检测率极低。后来把图片统一缩放到适合比例再预处理,问题解决。

对于Qwen3.5这类支持多模态加工具调用的模型,微调数据还需要包含工具调用记录。格式上要严格遵循它的约定,比如遇到需要调用工具的操作,要在指定的分隔符之间写入工具名和参数,否则模型看似能对话,但实际上学不会调用工具。

4.4 混合精度与数值稳定性

还有一个值得单独说说的点:混合精度训练。多模态模型默认用FP16或BF16混合精度来节省显存。BF16相比于FP16,指数位更多,表现力范围更大,深度模型中更不容易溢出。但在视觉任务中,FP16经常出现loss变成NaN的情况,这通常是因为视觉编码器输出的某些特征值过大,超过了FP16的表示范围。

我当时排查了很久才发现问题出在损失函数的数值范围上。物体检测的回归损失在前期会非常大,动态范围超过了FP16的表示上限。解决方式很简单:把损失函数中平方项前面的缩放系数调小一点,或者在损失计算前先除一个系数。如果你用的是现成框架如Unsloth,很多数值问题已经被处理掉,但这并不代表你可以完全忽略精度问题——训练过程中还是要持续监控loss曲线,一旦出现NaN,立即检查数据格式、学习率和混合精度的配置。

4.5 推理服务上线前后的排查清单

服务上线前,我习惯跑一遍完整的排查清单,可以大大减少线上事故的概率。

权重加载后先做一次前向推理,用最简单的图文输入验证模型能正常输出。如果输出乱码,优先检查tokenizer和模型的版本是否匹配,以及权重文件是否完整。然后测长文本输入,观察输出是否有截断或重复循环,如果出现循环,检查repetition_penalty参数设置。再做并发测试,看显存是否够用,不够的话调整批量大小或开启KV Cache复用。视觉输入要测试不同尺寸、不同分辨率、不同长宽比的图片,确认模型没有因为分辨率限制而无法处理。最后测工具调用能力,输入需要调用API的指令,确认模型能正确生成工具调用参数。

如果压测时发现首Token延迟过高,大多数原因是视觉编码阶段耗时过长。可以考虑对高频图像尺寸做缓存,或者把视觉编码器输出直接缓存起来复用,跳过重复的视觉特征提取。这套排查流程做过一遍之后,你会发现多模态模型上线没有想象中那么复杂,更多的其实是细节管理。

5. 架构选择建议与扩展思考

对不同需求,我给出一个相对明确的选型参考。

如果你的核心场景是图像理解、视频理解、文档OCR、物体检测,且你需要的视觉Token效率较高、对图像细节敏感,Qwen3-VL是最稳妥的选择。它在公开评测和实际业务中的视觉能力都经过了大量验证,社区工具链也比较成熟,微调时能找到大量现成的实践资料。

如果核心场景是纯文本生成,且资源有限、对延迟敏感,Qwen3-Next的MoE架构会让推理成本大幅下降。它的激活参数占比通常在20%到40%之间,相比稠密模型能节省一半以上的推理计算量。但需要留意的是,MoE模型的内存占用依然不低——哪怕只激活少部分专家,全部专家权重依然要加载到显存里。所以它的主要优势在于计算量而非存储量,选型时要算清楚这笔账。

如果你的目标是构建Agent应用,需要模型完成多模态理解、工具调用、代码生成、多轮推理这一整套流程,Qwen3.5的融合架构是追赶大趋势的合理选择。它把“感知、思考、行动”整合在一个模型里,避免了多模型拼接带来的上下文割裂和工程复杂度。

我个人在实际使用中的体会是,架构永远不是越新越好,关键看你手里的资源和任务匹配度。Qwen3-VL的优势在于“专注”,它把所有能力都押在视觉理解上,换来的是少见的稳定性和可控性;Qwen3-Next的优势在于“效率”,它把有限的算力全部用在刀刃上;Qwen3.5的优势在于“整合”,它试图用一套参数解决所有问题,但代价是训练和推理的复杂度都大幅提升。对于刚入门多模态开发的团队,从Qwen3-VL开始是最快能出成果的路径;对于已经把多模态应用跑通、想降本增效的团队,Qwen3-Next值得认真测一测;对于要做下一代Agent应用的团队,Qwen3.5值得关注,但也要做好工程复杂度的心理准备。

最后再分享一个实操细节。无论是用哪个模型,多模态数据的质量永远是第一位的。我见过太多团队在模型架构上花大力气,但数据标注质量粗糙,模型上线后性能就是上不去。先把数据的采集、清洗、标注规范做好,再把架构的选型做对,最后才轮到训练和推理参数的调优。这个顺序不要搞反。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/5 6:07:43

FPGA高速数据传输实战:AXI转PCIe与XDMA IP核配置详解

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

作者头像 李华
网站建设 2026/10/5 6:07:42

FMMT417雪崩三极管射频脉冲源设计与ADS仿真全流程解析

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

作者头像 李华
网站建设 2026/10/5 6:06:40

2461张VOC鸟巢数据集:输电线路巡检目标检测实战指南

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

作者头像 李华
网站建设 2026/10/5 6:06:33

工业液滴气泡多目标检测实战:YOLO数据集训练与密集小目标调参

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

作者头像 李华
网站建设 2026/10/5 6:06:15

Coze智能体实战:用工作流把PRD一键变成测试用例

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

作者头像 李华