大模型推理性能优化:Prefill与Decode瓶颈及KV缓存显存管理

1. 大模型推理的性能账本:为什么你的服务又慢又贵

搞大模型推理服务的人,迟早都会撞上同一堵墙:模型明明跑起来了,单条请求的延迟看着还行,可一旦并发上来,吞吐量死活上不去,GPU 利用率像心电图一样忽高忽低,显存却先一步爆了。你加卡、换更贵的型号、调 batch size,折腾一圈发现收益远没有想象中大。问题往往不在模型本身,而在于你没搞清楚推理这件事到底在拼什么。

把大模型推理拆开看,其实只有两个阶段:Prefill(预填充)和Decode(解码)。这两个阶段的性能瓶颈完全不同——Prefill 阶段是计算密集型,拼的是算力;Decode 阶段是访存密集型,拼的是显存带宽。而贯穿两个阶段、决定你能塞下多少并发、能跑多长上下文的,是KV 缓存,它直接决定了显存代价。这三件事构成了 LLM 推理性能的核心框架,理解它们之间的取舍关系,比盲目堆硬件有用得多。

这篇文章适合正在做推理服务部署的工程师、做模型落地的算法同学,以及任何被"吞吐上不去、显存不够用"折磨过的人。我会把 Prefill 和 Decode 的算力/带宽账算清楚,把 KV 缓存的显存开销拆到字节级别,再给出实际部署中真正管用的优化手段和踩坑经验。看完你至少能回答三个问题:我的瓶颈到底在哪、该往哪个方向优化、以及为什么有些优化看起来很美但实际没用。

2. Prefill 与 Decode:两个阶段,两套完全不同的性能逻辑

2.1 一次推理请求到底经历了什么

当你把一段 prompt 丢给模型,推理过程被切成两段。第一段是 Prefill:模型把整段输入 token 一次性喂进去,为每个 token 计算出 Key 和 Value 向量,存进 KV 缓存,同时算出第一个输出 token。第二段是 Decode:从第一个输出 token 开始,模型每次只生成一个 token,每生成一个就要把前面所有 token 的 KV 缓存读一遍,再算出下一个。

这个切分不是人为规定的,而是由自回归生成的本质决定的。Prefill 能并行处理整段输入,是因为输入 token 之间没有依赖关系,可以一次性算完;Decode 必须串行,是因为第 N 个输出 token 依赖第 N-1 个,没法并行。

理解这个区别是理解一切性能问题的起点。Prefill 像是一次性搬一整车货,Decode 像是每次只搬一件但要把整个仓库翻一遍。两者的资源消耗模式截然不同。

2.2 Prefill 为什么拼算力

Prefill 阶段处理的是长度为 L 的输入序列,模型要对这 L 个 token 做完整的注意力计算和前馈网络计算。注意力的计算量大致是 O(L²·d),其中 d 是隐藏维度;前馈网络是 O(L·d²)。当输入很长时,注意力那部分的平方项会迅速主导计算量。

关键在于,Prefill 阶段有大量可以并行的矩阵乘法,GPU 的 Tensor Core 能被充分喂饱。这时候 GPU 的计算单元是满负荷运转的,显存带宽反而成了次要因素——因为数据复用率高,算一次能用到很多次。所以 Prefill 的性能天花板由GPU 的浮点算力(FLOPS)决定,尤其是 FP16/BF16 的算力。

实测下来,Prefill 阶段 GPU 的计算利用率(MFU,Model FLOPs Utilization)通常能跑到 40% 到 60%,好的实现能到 70% 以上。这个数字说明算力确实被用起来了,瓶颈在算力本身。

2.3 Decode 为什么拼带宽

Decode 阶段每次只处理一个新 token,但要把 KV 缓存里所有历史 token 的 Key 和 Value 读出来参与注意力计算。假设上下文长度是 L,隐藏维度是 d,层数是 N,那么每生成一个 token,需要读取的 KV 缓存数据量是 2·L·d·N·2 字节(FP16 下每个数 2 字节,K 和 V 各一份)。

这个读取量随上下文线性增长,而计算量却很小——只有一次矩阵向量乘法。结果就是:计算单元大部分时间在等数据从显存搬过来。这就是典型的访存密集型(memory-bound)场景。

用一个生活类比:Prefill 像是让一群工人同时搬一堆砖,人多力量大;Decode 像是让一个工人每次只搬一块砖,但他每搬一块都要跑回仓库最里面取,跑腿的时间远大于搬砖的时间。这时候你加再多工人(算力)也没用,得把仓库搬到工人手边(提高带宽)或者减少跑腿次数(优化缓存)。

实测中 Decode 阶段的计算利用率经常只有个位数百分比,GPU 大部分时间在等显存。所以 Decode 的性能天花板由显存带宽(Memory Bandwidth)决定。

2.4 两个阶段的性能特征对比

维度Prefill 阶段Decode 阶段
计算模式矩阵-矩阵乘法为主矩阵-向量乘法为主
瓶颈类型计算密集型访存密集型
决定性能的硬件浮点算力(FLOPS)显存带宽(GB/s)
典型计算利用率40%~70%5%~15%
可并行性高,整段输入并行低,逐 token 串行
对 batch 的敏感度中等高,batch 能摊薄权重读取
优化方向算子融合、量化、并行KV 缓存优化、批处理、投机解码

这张表是整篇文章的骨架。你遇到的每一个性能问题,先判断它落在哪个阶段,再对照这张表找方向,基本不会跑偏。

3. KV 缓存:决定显存代价的那个隐形大户

3.1 KV 缓存到底占多少显存

KV 缓存的显存占用公式很直接:

KV 缓存大小 = 2 × 层数 × 注意力头数 × 头维度 × 序列长度 × batch_size × 数据类型字节数

其中 2 代表 K 和 V 各一份。以一个 70 亿参数、32 层、32 个注意力头、头维度 128 的模型为例,FP16 精度下每个 token 的 KV 缓存是:

2 × 32 × 32 × 128 × 2 字节 = 524288 字节 ≈ 0.5 MB

看起来不多,但注意这是每个 token。如果上下文长度是 8192,单个请求就是 4 GB;如果 batch_size 是 16,直接飙到 64 GB。而模型权重本身 FP16 下才 14 GB 左右。也就是说,KV 缓存很容易超过模型权重成为显存第一大户。

这就是为什么很多人发现:模型能加载进去,但一跑长上下文就 OOM。不是模型太大,是 KV 缓存把显存吃光了。

3.2 为什么 KV 缓存不能省

有人会问:既然 KV 缓存这么占地方,为什么不每次重新算?答案是计算代价太高。Decode 阶段每生成一个 token,如果不缓存,就要把前面所有 token 的 K 和 V 重新算一遍,计算量是 O(L²),而缓存后只需要 O(L) 的读取。在长上下文场景下,重算的时间成本是缓存的几十倍甚至上百倍。

所以 KV 缓存是用显存换时间的经典 trade-off。问题不在于要不要缓存,而在于怎么把缓存做得更省、更高效。

3.3 显存带宽如何成为 Decode 的硬约束

回到 Decode 阶段。每生成一个 token,需要读取的 KV 缓存是 0.5 MB(以上面模型为例)。如果显存带宽是 2 TB/s,那么理论上每秒能读取 400 万次这样的数据块,也就是每秒能生成 400 万个 token?这个数字显然太乐观了,因为还要算上模型权重的读取。

实际上,Decode 阶段每生成一个 token,除了读 KV 缓存,还要读一遍模型权重(因为每次只算一个 token,权重没法复用)。70 亿参数 FP16 是 14 GB,每生成一个 token 就要把这 14 GB 读一遍。在 2 TB/s 带宽下,光读权重就要 7 毫秒,也就是单请求每秒最多生成约 140 个 token。

这个计算揭示了一个关键事实:Decode 阶段的单请求速度被显存带宽死死卡住。要提升吞吐,只能靠 batch——多个请求共享同一次权重读取。batch_size 从 1 加到 16,权重读取的摊销成本降到 1/16,吞吐能提升十几倍。但 batch 一大,KV 缓存又成倍增长,显存又不够了。这就是推理服务里最核心的矛盾。

4. 从理论到落地:推理服务的优化实操

4.1 先定位瓶颈:你的服务卡在哪

优化之前必须先测量。我见过太多人上来就调参数,结果优化了个寂寞。定位瓶颈的方法很简单:

第一步,看 Prefill 和 Decode 的耗时占比。如果 Prefill 占大头,说明输入长、算力不够,往算力方向优化;如果 Decode 占大头,说明输出长、带宽不够,往缓存和批处理方向优化。

第二步,看 GPU 利用率曲线。Prefill 阶段利用率高、Decode 阶段利用率低是正常的;如果两个阶段利用率都低,说明有调度或框架层面的问题。

第三步,看显存占用构成。把模型权重、KV 缓存、激活值分开统计。如果 KV 缓存占比超过 50%,说明显存主要被缓存吃了,要优先做缓存优化。

提示:不要只看平均延迟,要看 P99 延迟。推理服务的用户体验由长尾决定,平均值会骗人。

4.2 Prefill 优化:把算力榨干

Prefill 的优化核心是提高计算利用率,让 Tensor Core 别闲着。

算子融合是最直接的手段。把 LayerNorm、矩阵乘、激活函数这些相邻算子合并成一个 kernel,减少 kernel 启动开销和中间结果的显存读写。FlashAttention 就是典型代表,它把注意力计算融合成一个 kernel,避免了中间注意力矩阵的显存读写,在长序列上提速明显。

量化是另一个大杀器。把权重和激活从 FP16 降到 INT8 甚至 INT4,算力需求直接减半或降到四分之一。但要注意,量化对 Prefill 的收益不如对 Decode 明显,因为 Prefill 本来就是算力瓶颈,量化主要省的是显存和带宽。

序列并行适合超长输入。当输入长度超过单卡能处理的范围,把序列切分到多张卡上并行计算,每张卡只处理一部分 token 的注意力。代价是卡间通信开销,适合输入特别长的场景。

4.3 Decode 优化:和带宽做朋友

Decode 的优化核心是减少显存读取量、提高读取效率。

连续批处理(Continuous Batching)是必选项。传统批处理要等一个 batch 里所有请求都生成完才能接下一批,GPU 在等待时是空闲的。连续批处理让每个请求独立进出,一个请求生成完立刻换下一个进来,GPU 始终有活干。实测下来,连续批处理能把吞吐提升 2 到 5 倍,是性价比最高的优化。

PagedAttention解决的是 KV 缓存碎片问题。传统实现里 KV 缓存要预分配连续显存,长度按最大可能值算,浪费严重。PagedAttention 把缓存切成固定大小的块,按需分配,显存利用率能从 20%~40% 提升到 90% 以上。这意味着同样的显存能塞下更多并发请求。

投机解码(Speculative Decoding)用一个小模型先猜几个 token,大模型再一次性验证。如果猜对了,就省下了大模型的多次前向。这个方法的收益取决于小模型的命中率,命中率高时能提速 2 到 3 倍,命中率低时反而拖慢。适合输出内容比较确定的场景,比如代码生成、结构化输出。

量化 KV 缓存是直接省显存的手段。把 KV 缓存从 FP16 降到 INT8,显存占用直接减半,带宽需求也减半。代价是精度损失,实测在多数任务上 INT8 KV 缓存的质量损失可以接受,但要注意校准。

4.4 关键参数的计算与选择

部署时几个参数必须算清楚,不能拍脑袋。

最大 batch size由显存决定。可用显存 = 总显存 - 模型权重 - 激活值预留。假设总显存 80 GB,模型权重 14 GB,激活预留 10 GB,剩 56 GB 给 KV 缓存。如果每个请求平均上下文 4096,每 token 0.5 MB,单请求缓存 2 GB,那么最大 batch 约 28。但这是理论上限,实际要留 20% 余量,取 22 左右。

最大上下文长度要和 batch size 权衡。上下文翻倍,单请求缓存翻倍,能支持的 batch 就减半。如果业务上大部分请求上下文很短,可以设置动态上限,短请求多塞、长请求少塞。

GPU 显存带宽是选卡的硬指标。做 Decode 密集型服务,优先选带宽高的卡,而不是算力高的卡。同样价格下,带宽翻倍带来的 Decode 吞吐提升,往往比算力翻倍更明显。

参数计算依据建议取值
最大 batch size(可用显存 - 权重 - 激活) / 单请求缓存理论上限的 80%
最大上下文业务 P95 上下文长度略高于 P95,留余量
KV 缓存精度质量要求与显存权衡FP16 优先,紧张时 INT8
块大小(PagedAttention)显存碎片与调度开销权衡16 或 32

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

5.1 吞吐上不去,先查这三处

第一处:batch 是不是太小。很多人为了降延迟把 batch 设得很小,结果 GPU 利用率上不去,吞吐自然低。Decode 阶段 batch 从 1 加到 8,吞吐通常能翻好几倍,延迟增加却很有限。先试着把 batch 调大,看吞吐和延迟的变化曲线,找到拐点。

第二处:KV 缓存是不是碎片化。如果显存明明还有,但新请求就是进不来,多半是缓存碎片。用 PagedAttention 或者检查缓存分配策略,看是不是预分配了过大的连续块。

第三处:调度是不是串行。检查请求队列的处理逻辑,是不是一个请求处理完才接下一个。连续批处理没开的话,GPU 会有大量空闲等待。

5.2 长上下文为什么特别慢

长上下文慢在两个地方。Prefill 阶段,注意力计算量随长度平方增长,输入从 2K 到 8K,Prefill 时间可能涨 10 倍以上。Decode 阶段,每生成一个 token 要读的 KV 缓存随长度线性增长,8K 上下文的读取量是 2K 的 4 倍。

应对方法:Prefill 用 FlashAttention 类的高效注意力实现,Decode 用 KV 缓存量化或滑动窗口注意力(只保留最近 N 个 token 的缓存)。滑动窗口会损失长距离依赖,适合对远期上下文不敏感的任务。

5.3 显存明明够却 OOM 的排查

这种情况通常是显存碎片或者峰值超限。排查步骤:

  1. 用显存分析工具看峰值占用,而不是平均值。Prefill 阶段的激活值峰值可能远高于 Decode。
  2. 检查是否有预分配的大块显存没释放。
  3. 看 KV 缓存的实际占用和理论值是否吻合,不吻合说明有泄漏或碎片。
  4. 临时把 batch 降到 1,看是否还 OOM,排除并发因素。

注意:PyTorch 的缓存分配器会保留已释放的显存,torch.cuda.memory_allocated和torch.cuda.memory_reserved要分开看,前者是实际使用,后者是保留量。

5.4 量化后质量下降怎么办

量化 KV 缓存或权重后质量下降,通常是校准没做好。几个经验:

  • 权重量化用 GPTQ 或 AWQ,比朴素的 round-to-nearest 好很多。
  • KV 缓存量化要按通道校准,不同通道的数值范围差异很大。
  • 先量化权重,质量可接受再量化 KV 缓存,逐步来。
  • 保留关键层(比如第一层和最后一层)的高精度,其余层量化,质量损失更小。

5.5 常见问题速查表

现象可能原因排查方向
吞吐低、GPU 利用率低batch 太小、调度串行调大 batch、开连续批处理
长上下文 OOMKV 缓存超限量化缓存、限制上下文、PagedAttention
Decode 慢带宽瓶颈、缓存读取量大缓存量化、滑动窗口、换高带宽卡
Prefill 慢算力瓶颈、注意力实现低效FlashAttention、量化、序列并行
显存够却 OOM碎片、峰值超限显存分析、PagedAttention、降 batch
量化后质量降校准不足换量化方法、保留关键层精度

6. 我踩过的坑和几条实在建议

做推理服务这几年,有几个坑印象特别深。有一次线上服务吞吐突然掉了一半,查了半天发现是某个请求带了超长上下文,把 KV 缓存撑爆,触发了缓存驱逐,其他请求的缓存被反复重建。后来加了上下文长度限制和优先级调度才稳住。这件事让我明白,推理服务的稳定性不只取决于平均情况,更取决于最坏情况。

还有一次为了省显存把 KV 缓存量化到 INT4,结果生成质量肉眼可见地下降,尤其是需要长距离推理的任务。后来改成 INT8 加关键层保留 FP16,质量回来了,显存也只多了不到 20%。量化不是越狠越好,要找到质量和成本的平衡点。

几条实在建议:第一,先测量再优化,别凭感觉调参;第二,连续批处理和 PagedAttention 是必选项,不开这两个,其他优化都是事倍功半;第三,选卡时 Decode 密集型服务优先看带宽,别只看算力;第四,长上下文场景一定要做缓存量化或滑动窗口,否则显存迟早爆;第五,压测要用真实流量分布,别用均匀分布的假数据,长尾请求才是真正的考验。

这个领域变化很快,新的注意力实现、新的量化方法、新的调度策略层出不穷。但底层那套账——Prefill 拼算力、Decode 拼带宽、KV 缓存决定显存——短期内不会变。把这套账算清楚,新东西出来你也能快速判断它值不值得上。

相关新闻

从零搭建代码评审自动化流水线:开源工具链选型与实操

从零搭建代码评审自动化流水线:开源工具链选型与实操

1. 从零搭建一套代码评审自动化流水线,我为什么盯上了 open-code-review代码评审这件事,干过几年开发的人都有体会:它既是保证代码质量最有效的手段之一,也是最容易流于形式的环节。团队小的时候,大家靠自觉&#xff0…

2026/10/21 0:46:35 阅读更多 →
Pod多容器资源共享:从Linux Namespace到Sidecar实战

Pod多容器资源共享:从Linux Namespace到Sidecar实战

1. 先搞清楚Pod里究竟共享了哪些东西做K8S这么久,有个问题几乎每次培训都会被问到:Pod里面多容器到底共享了什么资源?很多朋友一说“共享”,第一反应就是文件目录,觉得只要把同一个Volume挂进两个容器,就算…

2026/10/21 0:46:35 阅读更多 →
深入理解PostgreSQL Hybrid Hash Join:批次、内存与SQL调优

深入理解PostgreSQL Hybrid Hash Join:批次、内存与SQL调优

前阵子帮同事排查一条慢SQL,原本30毫秒的查询突然掉到9秒,EXPLAIN ANALYZE里明晃晃写着Batches: 8。经验告诉我这是work_mem设小了,hash join被挤出内存,但真正让我心虚的是:如果被追问一句"为什么Batches变成8就…

2026/10/21 0:46:35 阅读更多 →

最新新闻

永磁同步电机MTPA+弱磁+前馈补偿双闭环控制仿真解析

永磁同步电机MTPA+弱磁+前馈补偿双闭环控制仿真解析

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

2026/10/21 1:26:01 阅读更多 →
电压电流检测方案全解析:从分压电阻到隔离ADC的选型指南

电压电流检测方案全解析:从分压电阻到隔离ADC的选型指南

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

2026/10/21 1:26:01 阅读更多 →
Octop 自托管 AI 助手 API 文档实战指南:5 步从开启 /api/docs 到调通第一个接口

Octop 自托管 AI 助手 API 文档实战指南:5 步从开启 /api/docs 到调通第一个接口

Octop 自托管 AI 助手 API 文档实战指南:5 步从开启 /api/docs 到调通第一个接口 【免费下载链接】Octop A smarter, self-hosted AI assistant — multi-user, multi-agent. 项目地址: https://gitcode.com/GitHub_Trending/oct/Octop Octop 是一个多用户、…

2026/10/21 1:26:01 阅读更多 →
ABS建模核心:滑移率物理本质与制动器动态建模

ABS建模核心:滑移率物理本质与制动器动态建模

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

2026/10/21 1:26:01 阅读更多 →
盘点8款出圈国产AI芯片:从云端训练到端侧语音怎么选

盘点8款出圈国产AI芯片:从云端训练到端侧语音怎么选

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

2026/10/21 1:26:01 阅读更多 →
深入parakeet-redux架构:从24层TDT编码器到解码器的设计细节

深入parakeet-redux架构:从24层TDT编码器到解码器的设计细节

人工智能语音模型量化模型压缩 【免费下载链接】parakeet-redux 项目地址: https://ai.gitcode.com/hf_mirrors/moondream/parakeet-redux 点击查看 免费下载 🦜 parakeet-redux 是一个 1.58 bit 三值量化的自动语音识别(ASR)模型…

2026/10/21 1:25:00 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事:AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里,按宣传口径,本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”,而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起:用户到底在追求什么“封号重开”这四个字,放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流,背后是大量的时间和精力成本。正常情况下,没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”,而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时,就意识到:单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →