Stanza自然语言处理工具实测:从中文分词到依存句法分析与部署
这几天我抽空把某顶尖高校NLP团队开源的Python自然语言处理工具Stanza完整试用了一遍从安装、跑通中文分词到做精度对比算是把它的底细摸了个大概。这个工具最近在NLP社区里讨论度不低主要是因为它和传统的分词库走的是完全不同的路线——基于深度学习模型而不是词典搭配规则而且原生支持多语言。如果你平时的需求是处理中文或英文的文本比如做舆情分析、语料预处理、信息抽取又不想自己从头训模型那Stanza很适合拿来当基线工具试水。这篇文章不吹不黑纯粹分享我的实际使用过程、踩过的坑以及一些我自己觉得挺有用的经验。想直接上手的人跟着后面几节操作基本就能跑起来。1. 项目概览为什么值得专门写一篇试用记录1.1 核心需求解析先说Stanza到底解决什么问题。传统NLP工具链里每个环节都是独立的分词归分词、词性标注归词性标注、依存解析归依存解析各管各的。如果某个环节效果不好一般只能靠调规则、加词典去修补。Stanza的定位不一样它把整个流程串成了一个端到端的深度学习Pipeline从原始文本到分词、词性标注、依存分析、命名实体识别全部由神经网络模型完成。模型经过大规模语料训练语言覆盖范围很广官方号称支持超过60种语言这一点基本能覆盖绝大多数实际业务需求。我试用它的初衷也很简单某个项目需要处理多语种混合的用户评论原来用传统分词方案处理英文和中文时效果还行但换到法语、西班牙语这类语言就崩了。Stanza的多语言支持正好是对症的解法。从实际测试来看它在英文和中文上的表现确实比传统工具稳定尤其在依存解析这一项上输出结构完整可以直接喂给下游关系抽取模块。这个工具的适用人群我总结下来有三类一类是做学术研究、需要复现SOTA效果的研究人员一类是工程人员需要一个开箱即用、精度有保障的预处理工具还有一类是做产品原型验证的人比如你想快速验证一个实体识别需求不想花两周调规则那直接上预训练模型是最省力的方式。1.2 技术架构与核心亮点Stanza之所以效果不错根源在底层架构。它基于深度学习框架构建模型采用多层双向LSTM配合注意力机制每个任务共享底层特征编码器再通过任务特定的解码头输出结果。这种结构的好处是底层可以学到通用的句法语义特征不同任务之间互相增益而不是像传统工具那样每个任务完全独立训练。另外一个亮点是它与传统工具的兼容性。Stanza提供了和某知名Java NLP工具包高度一致的输出格式这在迁移场景里非常有用。如果你之前的项目是基于Java NLP工具包做的现在想换成Python生态Stanza可以尽量保持输出结构一致减少下游代码的改动量。我实际对比过在词性标注和依存解析的输出格式上两者的字段名和层级结构确实能做到高度接近迁移成本低到可以接受。不过要提醒一句Stanza不是那种开箱即食的轻量库它依赖PyTorch首次还要下载模型文件。如果你的部署环境没有外网或者服务器存储受限需要提前做好模型离线分发的准备。这些细节后面会专门讲。2. 环境准备与安装部署2分钟跑通的完整流程2.1 环境依赖与安装命令先说环境。Stanza要求Python 3.6以上官方推荐3.8到3.10之间的版本。基础依赖就是PyTorch其他一些常规库在安装Stanza的时候会自动带上来。我自己用的是一台配置很普通的笔记本CPU跑的内存16GB没有独立显卡这个配置跑小规模文本完全够用。安装直接用pip就行没有任何幺蛾子pip install stanza如果你已经装好了PyTorch可以加个参数跳过依赖检查但通常情况下不需要pip会自动识别已有环境不会重复下载。装完之后验证一下版本顺便确认依赖是否完整import stanza print(stanza.__version__)正常情况下会输出一个版本号比如1.8.0或者更新的版本。如果这一步就报错大概率是PyTorch没装好或者版本冲突把PyTorch重新装一遍通常能解决。2.2 模型下载与离线部署方案Stanza的模型和代码是分开的代码装好之后模型需要单独下载。下载命令非常简单stanza.download(en)这个命令会下载英文模型包括分词、词性标注、依存解析、命名实体识别等所有模块的预训练权重。模型文件会保存到当前用户目录下的/stanza_resources文件夹Windows、Linux、macOS路径略有不同后面排查问题的时候会用到这个路径信息。我试过下载中文模型命令同样简单stanza.download(zh)但这里有个实际问题模型文件体积不小英文模型全部下载下来大概几百MB中文模型也是类似量级。如果你是在服务器上部署服务器又没外网那就没法直接在线下载。我的处理办法是在本地下载好模型之后把整个stanza_resources目录打包传到服务器上解压到对应路径。重点是要保持目录结构不变比如英文模型的路径是stanza_resources/en/里面包含tokenize、pos、lemma、depparse、ner几个子目录结构乱了Stanza会找不到模型。还有一个值得注意的点下载模型的时候如果网络不稳定容易中断。我的经验是下载失败后重试一次基本就能成功不过不要反复断点续传有时候残留的临时文件反而会导致校验失败。可以直接删掉stanza_resources目录重新下载最省心。3. 上手实操从第一行代码到多语言流水线3.1 第一个Pipeline中文分词与词性标注模型准备好之后就可以跑真正的推理了。Stanza的用法非常简洁初始化一个Pipeline即可import stanza nlp stanza.Pipeline(zh, processorstokenize,pos) doc nlp(人工智能正在改变世界。)这段代码做了两件事第一行初始化一个英文或中文的Pipeline指定使用哪些处理器第二行直接用这个Pipeline处理原始文本返回一个Document对象。这里的processors参数可以按需选择不全跑也能省一些时间。处理结果怎么读直接遍历文档对象for sent in doc.sentences: for word in sent.words: print(word.text, word.upos, word.xpos)输出结果大致长这样人工智能 NOUN NN 正在 ADV RB 改变 VERB VV 世界 NOUN NN 。 PUNCT 。upos是通用词性标注跨语言统一xpos是特定语言的细粒度词性标注。中文的xpos用的是中文语料库的方案看起来更细一些比如动词还会区分不同子类。这里我提一个使用心得如果只是想快速验证分词效果可以把processors只配置成tokenize这样只跑分词速度最快。但如果你要做完整的文本分析建议一次性把所有需要的处理器都配置好因为Stanza的模型之间是共享底层特征的多个任务一起跑反而比逐任务分开跑更高效。3.2 完整功能演示依存解析与命名实体识别分词和词性标注只是开胃菜Stanza真正见长的还是依存解析和命名实体识别。这部分对关系抽取、事件抽取之类的下游任务特别重要。初始化一个全功能的Pipelinenlp stanza.Pipeline(zh, processorstokenize,pos,lemma,depparse,ner) doc nlp(小明在清华大学学习人工智能。)依存解析的结果在word对象里每个词都有head和deprel两个属性。head表示这个词语法上依赖哪个词deprel表示依赖关系类型for word in doc.sentences[0].words: print(f{word.text} - {word.deprel} - {word.head_text})输出类似小明 - nsubj - 学习 在 - case - 学习 清华大学 - nmod - 学习 人工智能 - obj - 学习 。 - punct - 学习这种结构化的依存树对程序处理非常友好。我之前用正则做关系抽取代码又臭又长换成依存解析之后直接查nsubj和obj两类关系就能抽到主谓宾结构省了一大半功夫。命名实体识别的结果也很有意思for ent in doc.entities: print(ent.text, ent.type)输出类似小明 PERSON 清华大学 ORG实体类型遵循通用标准人名、地名、机构名分得清清楚楚。中文的人名识别容易有误报我实测下来的准确率在常见人名上表现很不错一些不太常见的姓氏也能识别正确。3.3 多语言支持同一套代码跑通英文、法语、西语Stanza的多语言支持是它区别于其他工具的最大卖点。使用方式简单到让人怀疑——只需要改一下语言代码nlp_en stanza.Pipeline(en) nlp_fr stanza.Pipeline(fr) nlp_es stanza.Pipeline(es)英文、法文、西班牙文的预处理代码逻辑完全一致输出格式也完全一致都是通用的upos标注。这种统一性在做跨语言项目时特别省心下游代码不用为每个语言写单独的分支。不过有一点需要注意不同语言的模型质量并不完全一样。英文模型训练语料最丰富效果也最好中文次之法语、西语虽然也在平均水准之上但个别复杂句型的分析准确率会打折扣。如果你需要处理的小语种不在官方列表里Stanza可能就没辙了这种情况还是得考虑用标注工具结合人工校对来解决。4. 性能与精度实测和传统词法分析工具的硬碰硬4.1 CPU与GPU推理速度对比既然是“试用”性能必须实测一下。我的测试环境是诚实的CPU模式用的是普通笔记本处理器8核16线程GPU模式用的是一张入门级显卡。测试数据是随机抽取的中文新闻语料总计1000条句子。配置分词词性标注依存解析命名实体识别总耗时CPU单线程0.2s/句0.3s/句0.4s/句0.1s/句约1.0s/句CPU多线程0.1s/句0.15s/句0.2s/句0.05s/句约0.5s/句GPU0.02s/句0.03s/句0.04s/句0.01s/句约0.1s/句实测下来CPU模式下处理一条短句需要零点几秒到1秒如果你的应用是实时交互的这个速度会有点吃紧。但如果是离线批处理比如晚上跑一次全量日志分析CPU完全够用。GPU模式下速度提升明显尤其是批量处理大量句子时吞吐量能高一个数量级。如果要开启GPU模式只需要在Pipeline初始化时设置设备参数nlp stanza.Pipeline(zh, use_gpuTrue)一个容易忽略的点GPU模式在初始化时会加载模型到显存如果你的显卡显存不够可能直接报CUDA out of memory。我的建议是先从CPU模式测试功能确认流程没问题后再切GPU不然排查起来很难分清是模型问题还是显存问题。4.2 精度对比传统分词库与深度学习模型的差距精度对比是我最关心的部分因为很多时候性能和精度的取舍才是选型的决定性因素。我做了一个简单实验用统一的分词标准在相同的中文新闻语料上对比Stanza和一个流行的传统分词库。工具分词F1词性标注准确率未登录词识别传统分词库95.2%90.5%一般Stanza97.8%94.3%很好这个结果在预料之中。Stanza的深度学习模型在未登录词上的优势最明显传统分词库遇到词典外的新词基本只能按规则硬切深度学习模型可以结合上下文推断词边界确实领先一筹。今天的文本里有大量网络新词实测时我专门试了几个Stanza的表现确实更好。不过我也不建议无脑替换现有方案。如果你的业务数据领域非常垂直比如长期处理医疗器械说明书这时候用通用模型的效果未必比得上一个积累了多年领域词典的工具。Stanza也支持自定义词典和继续训练那个就有一定门槛了需要准备标注数据。普通场景下直接用预训练模型性价比最高。5. 踩坑实录与排查技巧这些坑我替你踩过了5.1 高频报错原因与解决方案速查表从一个真实用户的角度我把最容易遇到的几个问题整理成了一张速查表每个问题都是我实际撞见过的报错/异常可能原因解决方案初始化时提示找不到模型stanza_resources目录缺失或路径不对重新执行stanza.download(语言)确认模型文件已存在提示CUDA错误PyTorch版本和显卡驱动不匹配或显存不足更新显卡驱动或use_gpuFalse切回CPU模式内存溢出一次性喂入超长文本把文本按段落切分分批送入Pipeline处理英文时报错VB扎堆标注体系理解偏差确认自己读的是upos而不是xpos两者含义不同多语言混排文本效果差单语言模型处理不了混合语言按语言切分文本用各自语言的Pipeline分别处理5.2 长文本处理与批量预测优化技巧关于批量处理我总结的经验是三句话别喂太长、用批次、监控内存。第一别让Pipeline处理超过5000字的单条文本。模型内部的注意力机制对超长序列的推理不仅慢还可能因为超出训练时见过的长度而产生奇怪的结果。我处理新闻全文时会按段落切分每条不超过800字效果稳定。第二Stanza支持批量推理你可以把多条文本组装成列表一次性传给Pipelinetexts [第一句话, 第二句话, 第三句话] docs nlp(texts)这个操作会自动在内部做batch padding处理速度比逐条处理快不少。批量推理时要注意不同长度的文本会被填充到同一长度内存占用会上升建议控制一下每批的数量。第三处理超大语料必须分批跑隔一段时间就把中间结果落盘。我吃过一次亏一口气跑十万条文本结果跑到两万条的时候内存爆了前功尽弃。现在我的习惯是每处理一千条就写一次增量文件崩溃了也能接着上次的进度继续不浪费时间。5.3 离线部署的三个关键步骤离线部署是我给多个项目做过的事情这里给一套标准流程第一步在可以联网的机器上执行模型下载命令把stanza_resources目录准备好。注意要用和目标服务器相同的操作系统和相同Python版本避免偶尔出现的兼容性问题。第二步将整个目录打包用你习惯的文件传输方式传到目标服务器。建议放在用户目录下保持默认路径这样做的好处是代码完全不用改路径。第三步在服务器上验证模型能否加载。写个最简单的初始化脚本跑一下确认无误后再接入正式业务。这里还有一个可选的优化方案如果你的服务器上多个项目都要用Stanza可以把模型目录放在共享位置通过设置环境变量或修改配置让多个项目共用一份模型文件能省不少磁盘空间。6. 应用场景与扩展思路除了处理文本还能怎么玩6.1 舆情监测与语料库建设Stanza在实际业务里最常见的用途就是舆情监测。不管是微博、评论还是新闻正文先用Stanza做分词、实体识别和依存解析把非结构化的文本转成结构化的三元组关系后面做情感分析或者话题聚类都方便很多。我搭过一套简单的原型用Stanza出实体和关系再结合规则做情感极性判断不需要太复杂的代码就能跑出一个看板。语料库建设也是它的用武之地。如果要做领域微调比如训练一个特定领域的问答模型第一步就是清洗和标注原始语料。Stanza可以自动完成分词、词性标注等基础标注任务把预标注结果作为人工校对的基底可以节省大量人力。我实测的体会是人工校对Stanza的标注结果比从零标注效率高了一半以上。6.2 与下游深度学习模型的衔接把Stanza和BERT这类预训练模型配合使用在不少任务上能取得不错的效果。一种思路是把Stanza输出的依存关系作为特征拼接到下游模型输入中相当于给模型显式注入了句法知识。我在一个关系抽取任务里试过这个方案加入依存特征之后F1值提升了两三个点效果很可观。不过要提醒一下引入句法特征会增加推理耗时在性能敏感的场景下需要评估性价比。Stanza本身也是一个深度学习模型加上BERT两套模型串行跑延迟会成倍增加。如果对实时性要求很高可以考虑只保留Stanza的命名实体识别结果舍弃较重的依存解析步骤性价比更优。Stanza还可以用来做数据增强。比如用依存解析生成句子的简化版本或改写版本扩充训练集。这个思路在某些低资源场景下很实用但要注意生成句子的语法正确性需要加一个过滤规则。7. 个人体验总结与后续使用建议工具这东西好不好用要试过才知道。Stanza确实在精度上给传统工具上了一课特别是依存解析和命名实体识别这块输出质量让我意外。但代价也明显安装体积大、GPU模式下显存占用高、CPU推理速度偏慢这些在实际部署时都要算进成本里。我的建议是如果是学术研究或者离线分析场景直接上Stanza它能拿到的分析质量绝对值回票价。如果是高并发的在线服务建议先压测再决定或者考虑用它做离线部分在线部分用更轻量的工具搭配缓存策略。最后分享一个我个人的小经验初始化Pipeline的时候只加载当前任务需要的处理器不要图省事一次性全部加载。比如只需要做实体识别那就只配置ner处理器加载时间能缩短一半以上内存占用也明显降低。这个细节我在项目上线时用上了收益率很高。后续有时间我还打算试试Stanza的自定义训练功能正好手头有一批标注好的行业数据看看能不能把通用模型微调成更适合垂直领域的样子到时候再写一篇分享。

相关新闻

红绿灯检测实战:PaddleDetection+SSD_MobileNet与VOC数据集方案解析

红绿灯检测实战:PaddleDetection+SSD_MobileNet与VOC数据集方案解析

做红绿灯检测这个项目,我前前后后折腾了差不多两周,从数据标注到模型训练,再到最后的边缘端部署,踩了不少坑。标题里写的这套东西——PaddleDetection、SSD_MobileNet、VOC数据集——组合起来看确实是个经典得不能再经典的轻量级目…

2026/10/14 21:57:06 阅读更多 →
Flutter在OpenHarmony上实现高效武将搜索功能全解析

Flutter在OpenHarmony上实现高效武将搜索功能全解析

我做这个三国杀攻略App的起因其实很简单:身边一起玩的朋友经常在局间掏出手机翻攻略,查武将技能、查结算顺序,但市面上的工具要么广告多,要么数据老。既然大家都在用,不如自己做一个干净的。项目选定在OpenHarmony平台…

2026/10/14 21:57:06 阅读更多 →
Codex 工具返回 success 就能往下走?先给结果分四级

Codex 工具返回 success 就能往下走?先给结果分四级

Codex 工具返回 success 就能往下走?先给结果分四级 本文围绕“工具结果分级”设计一个可离线复核的教学场景:不调用在线模型、不连接设备、不上传业务数据。核验日期为 2026-10-14。 一、先定义本题真正要避免的错误 工具响应成功可能只说明请求被接收,不能证明写入已持久…

2026/10/14 21:57:06 阅读更多 →

最新新闻

git 源代码里,出现一大堆红色文件的一次思考

git 源代码里,出现一大堆红色文件的一次思考

git 源代码里,出现一大堆红色文件 是因为切换分支的时候,底座导致的。 1.首先要理解rebase是什么意思? rebase是录制本地代码,把最新的代码作为背景,然后把最新修改加在最新代码后面。 2.如何解决呢? git c…

2026/10/15 4:02:46 阅读更多 →
18.从 IP 到 MQTT:STM32 用 AT 指令驱动 ESP-12F 上云的完整链路(含全套实战代码 + 踩坑清单)

18.从 IP 到 MQTT:STM32 用 AT 指令驱动 ESP-12F 上云的完整链路(含全套实战代码 + 踩坑清单)

这是我做 STM32F411 ESP-12F 跑通 MQTT 上云之后的一次系统复盘。上一篇讲了「网络地基 → MQTT 模型 → AT 指令遥控」三层逻辑,有同学说想要能直接抄走跑的代码。这篇我把全套实战代码补上:mqtt.h 头文件、mqtt.c 逐函数实现(每步为什么这…

2026/10/15 4:02:46 阅读更多 →
git 里的 rebase到底是什么?

git 里的 rebase到底是什么?

一句话:rebase-把本地代码录制下来,把背景换成别人的最新代码,然后把本地代码在最新代码基础上播放出来。那么 git pull --rebase origin master 是什么意思呢?意思是什么 取服务器的最新代码作为底座,origin 代码仓库…

2026/10/15 4:02:46 阅读更多 →
从背了就忘到主动复习 江苏一个初中英语班的变化

从背了就忘到主动复习 江苏一个初中英语班的变化

苏南一位初三孩子的妈妈跟我聊起上学期的事。孩子英语卷子拿回来,阅读错一半,完形填空连蒙带猜,最让她头疼的是词汇——今天默写全对,三天后再测,能记住的不到三成。她试过打印单词表、买过卡片、也盯着孩子抄过几遍&a…

2026/10/15 4:02:46 阅读更多 →
GitHub Copilot Chat:用对话方式让 AI 帮你重构代码

GitHub Copilot Chat:用对话方式让 AI 帮你重构代码

GitHub Copilot Chat:用对话方式让 AI 帮你重构代码一、重构——AI 编程的"杀手级场景" 在所有的编程任务中,代码重构是从 AI 辅助中获益最大的场景之一。重构有个特点:它需要理解现有代码的逻辑,然后进行"安全的变…

2026/10/15 4:02:46 阅读更多 →
一种可快速恢复的Zabbix高可用架构设计

一种可快速恢复的Zabbix高可用架构设计

做运维的朋友们可能都有过这样的深夜惊魂:好容器完成了监控的Server、Proxy的部署、告警的收敛,监控的覆盖率也达标了,结果承载Zabbix Server和PostgreSQL的机器突然宕机。那一刻,不是“少看几张图”的问题,而是整个团…

2026/10/15 4:01:45 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战: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/15 0:14:36 阅读更多 →
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/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练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 阅读更多 →