LLM推理性能优化:KV Cache与Prefill-Decode分离调优
每个做大型语言模型推理部署的人迟早都会碰到同一个问题显存不够了但吞吐还没提上来。我在学习笔记第四篇的时候整理过KV Cache的基础概念当时只是把它当作“计算过程的副产品”一笔带过现在回过头来看确实太天真了。PreFill阶段和Decode阶段对硬件资源的消耗规律完全不同KV Cache在这两个阶段里的生命周期、访存压力、容量规划也各有各的坑如果还按照“显存塞得下就万事大吉”的思路去做性能调优注定要踩大坑。这篇笔记是第十八篇我把它定位成“高级调优”重点说清楚两件事第一为什么Prefill和Decode必须分开看第二KV Cache从“能跑”到“跑得又稳又快”到底需要动哪些手术。内容会比较硬核涉及分布式推理中的显存规划、调度策略和量化取舍但我会尽量用实际操作过的案例来讲保证每一段都有代码或命令可以对得上号。1. Prefill-Decode分离架构的底层逻辑一开始我也犯过一个典型错误用同一个优化策略去压两个阶段。明明Prefill阶段在拼命做矩阵乘法Decode阶段在拼命做内存搬运我却指望同一个参数配置能同时满足两者的需求结果就是首Token延迟降不下去吞吐量也上不来。直到把两个阶段彻底拆开分别做性能分析才意识到这套分离架构是所有高级优化的前提。1.1 Prefill阶段算力密集与内存控制的博弈Prefill阶段的特点是“一次塞进去大量Token并行计算”。你给模型一个256长度的Prompt它可以在同一个step里把所有位置的Query、Key、Value都算出来并且同时生成这些位置对应的注意力分数。这个过程完全是矩阵乘法的天下计算强度极高GPU的Tensor Core可以被压得很狠。举个例子我用一套模拟某跨平台系统做基准测试一个13B的模型在Prefill阶段处理2048个Token时计算时间占了整体耗时的86%左右而访问显存搬数据的时间只占一小部分。因此这个阶段的优化重心应该是“怎么让更多的计算塞在同一个时钟周期里”也就是提高计算密度。但这里有一个暗坑Prefill阶段虽然算得快但中间激活值非常吃显存。矩阵乘法的中间结果、LayerNorm的临时张量、Softmax的归一化因子全都要写进显存。如果你无脑把Batch调大一个批次的Prefill就可能把显存撑爆反倒拖慢了整体节奏。我个人的做法是给Prefill阶段单独设置一个“批量上限”跟Decode阶段的批量分开互不干扰。提示不要为了追求Prefill阶段的计算利用率把Batch无限制拉大。要记住Prefill是突发的、算力密集的Decode是持续的、带宽受限的两者的最优Batch值往往相差好几倍。分开设置Batch是分离调优的第一步。1.2 Decode阶段从算力瓶颈到内存带宽瓶颈Decode阶段实际上是一个“一个Token一个Token往外挤”的过程。这个阶段每次只生成一个新的Token它需要读取所有的KV Cache去计算每个历史Token跟当前Token的注意力分数然后再加权求和。理论上计算量不大但问题在于整个自回归过程是串行的每一次迭代都要重新读一遍全部KV Cache这导致Decode阶段的访存量极大最终被显存带宽给卡死计算核心大部分时间在“摸鱼”。我在同一套模拟系统上测过Decode阶段的计算利用率有时候连20%都不到但显存带宽几乎拉到了接近峰值。这就是为什么大家常说“Decode是访存密集型”的原因。如果你在做性能工程心里必须有这根弦——Decode阶段的性能指标不是看TFLOPs而是看“每秒能搬多少字节”。换句话讲KV Cache的存储格式、内存布局、压缩方式直接决定了Decode能跑多快。想要系统性地优化必须先建立一条清晰的分界线Prefill看计算时间Decode看访存时间。Prefill的调优工具是矩阵分块、算子融合、并行切分Decode的调优工具是KV Cache缓存策略、内存池管理、批量调度。把这条分界线搞明白后面的高级操作才不会走偏。2. KV Cache性能瓶颈与设计取舍既然说Decode阶段的性能被访存卡死那访存的对象到底是什么就是KV Cache。KV Cache的大小随序列长度线性增长随层数和注意力头数线性增长看公式就能感受到压力单个请求KV Cache大小 ≈ 2 × num_layers × num_kv_heads × head_dim × seq_len × bytes_per_element公式里的“2”对应Key和Value两个张量bytes_per_element就是精度相关的字节数。FP16下是2字节INT8下是1字节。把这个公式随手算一下一个70B量级的模型序列长度到16K层数几十层KV Cache大小能达到几十GB级别。更麻烦的是在线服务是并发处理的每多一个并发请求缓存总量就翻一倍显存爆炸就在一瞬间。2.1 KV Cache的内存增长模型我自己调试时喜欢用一个更工程化的视角把KV Cache拆成“容量”和“开销”两个部分。容量就是上面公式算出来的字节数这个所有人都能想到。开销则是缓存分配、索引、填充过程中的额外显存消耗比如预留的空位、padding带来的浪费。在推理框架里如果你动态扩容缓存可能会弹出一大块连续显存这就是额外开销如果缓存碎片化空闲块无法合并那更是无底洞。为了直观看到缓存到底吃了多少显存可以在运行推理时打开内存监控每隔几十毫秒抓一次显存快照再把推理框架里的缓存池大小调出来比对。我干过一次一个16K序列长度的请求KV Cache占了显存总量的八成以上剩下的空间连个中间激活都放不下。这种场景下根本不缺算力缺的就是缓存规划和压缩手段。2.2 共享KV Cache与内存复用策略解决缓存爆炸的第一招是让不同请求尽可能共享相同的Prefix。你在做多轮对话时每一轮都带上了前面的历史内容这些历史内容的KV Cache其实可以复用不需要每个新请求都从头算一遍。比如系统提示词、文档前缀、公共指令这些往往在大量请求里重复出现如果你能把它们对应的KV Cache缓存起来新请求进来直接复用就能省掉一大块Prefill时间。但这里有个设计取舍缓存复用需要引入LRU之类的淘汰策略缓存的存储空间有限命中率不高的话反而浪费了管理成本。我个人的做法是先统计线上请求的Prefix重复度如果重复度确实高再上共享KV Cache如果请求五花八门那干脆把精力花在压缩单请求缓存上效果更直接。内存复用策略还包括“缓存池化”简单说就是一次性分配一块大内存把不同请求的KV Cache都按块挂在这块池子上请求结束就释放块下一个请求可以直接覆盖。这比频繁申请、释放小块显存高效得多也能避免显存碎片化。我在实际项目中用池化方案后显存碎片率从两位数降到了个位数以下吞吐提升非常明显。3. 高级KV Cache调优实操从内存到吞吐这一章直接上硬菜。我刚才提到的公式和池化其实都停留在“存量优化”阶段真正要突破内存天花板必须引入更高级的KV Cache管理手段。最值得投入的三个方向是分页KV Cache、KV Cache量化和动态批次调度。这三个方向我都在不同项目里验证过下面把步骤和取舍一五一十写出来。3.1 分页KV Cache的操作细节分页KV Cache这个名字听起来复杂但思想上特别像操作系统的分页把KV Cache划分成固定大小的块以块为单位分配和释放不需要整段连续显存。传统做法是整个序列的KV Cache必须连续存放序列一变长就得重新分配一大段内存不仅浪费而且拷贝开销巨大。分页之后每个请求的KV Cache按块挂起来逻辑上连续物理上可以散布想扩就扩想缩就缩。实际操作的时候你首先要决定“块大小”。块太大内部碎片浪费多块太小索引管理开销变大。我在几个测试模型上跑过不同块大小发现块大小设为256个Token或者512个Token比较均衡太小了页表膨胀太大了小请求浪费空间。这个值最好根据你的典型请求长度来定不要盲目签到别的项目里。其次是分配策略。分页KV Cache通常配一个全局的块表每个请求维护自己的块列表。新Token进来时先看当前块的剩余空间装得下就直接写装不下就申请新块。请求结束后所有块全部归还块表。这一步很关键如果释放逻辑写得不干净内存泄漏会让人血压拉满。我在代码里会用一个专门的BlockManager类来管理每次分配和释放都打印日志方便排查。需要强调的是分页KV Cache不仅仅是为了省内存更是为了支持“动态序列长度”。在线服务里有的请求生成长度只有几十个Token有的请求要生成上千个Token传统连续分配方案很容易被最长的那个请求撑爆分页方案可以按需扩容让显存使用率明显提升。我在一个模拟并发场景里把传统连续分配方案换成PagedKV方案同等显存下能支持的并发请求数几乎翻了一倍吞吐提升比压缩KV Cache来得更粗暴。3.2 KV Cache量化与精度权衡分页解决的是“存得下”的问题量化解决的是“少存点”的问题。KV Cache量化最常见的是把FP16的Key和Value压缩成INT8甚至更激进的4bit。这样做的好处极其直观缓存容量直接减半甚至减到四分之一Decode阶段读缓存时带宽压力也跟着下降。坏处则是数值精度损失可能导致模型生成的多样性下降或者出现一些细节错误。我在一个7B模型上做实验跑了一遍KV Cache INT8量化序列长度固定为4096模型困惑度几乎没变准确率掉得很少但显存占用下降了45%左右。这个性价比很高。更有意思的是在很多场景里Value的敏感度比Key高量化Key影响小量化Value容易掉点。所以你完全可以把Key和Value用不同精度存比如Key用INT4、Value用INT8。这个操作听起来花哨但实际落地并不复杂关键要看你的推理框架是否暴露了逐张量精度的配置接口。调优过程中还有一个小技巧按Channel做量化比逐Tensor量化效果好得多。逐Tensor量化是用整个缓存张量的最大值和最小值去做缩放而Value里各列的数值范围可能差异很大逐Tensor会把那些分布很窄的列给压坏。按Column或者按Head做量化每个列用单独的比例因子精度损失会小很多代价只是缩放因子的存储和计算开销略微上升。我在调优时几乎默认使用Per-Head或者Per-Channel的量化方式。注意量化模式转换本身需要时间如果你在推理过程中动态做量化反而可能拖慢速度。我更推荐架构层面的做法——模型加载时就把K和V的缓存按量化格式申请好推理过程中只做“写入时量化”不要在每次读取时再去反量化否则带宽优化就会变成带宽灾难。3.3 动态批次调度与抢占策略上面讲的都是单请求缓存优化可性能工程最终的落脚点是整个系统的吞吐。吞吐的核心在“如何让不同进度的请求共享同一个计算批次”。Decode阶段每个请求生成Token的速度不一样如果你把所有请求硬塞进同一个Batch必须等最慢的那个Token生成完其他请求就得在那白白等待。这就是经典的不均衡问题。动态批次调度业界叫Continuous Batching思路就是把“等待全部结束”变成“随时插入新请求”。某个请求在当前步骤生成了一个Token下一个步骤它不需要了那就把它从批次里摘掉再把一个新的等待中的请求插进来。实现这套机制最大的难点不是调度逻辑而是KV Cache的空间规划。因为每个请求的KV Cache是独立的你必须在调度器里维护一张“哪个请求当前占用哪块Cache”的映射插入新请求时要确保有足够的空块。实操层面我建议直接使用推理框架里的Continuous Batching开关把它打开后用压测工具模拟混合长短期请求观察每秒生成Token数和首Token延迟。有一回我把调度机制打开后P99延迟反而变高了原因很诡异——调度器过于激进频繁插入新请求导致每个step的上下文切换开销增大。后来我限制每个step最多插入2个新请求延迟抖动立刻消失了吞吐还稳步提升。所以调度器的激进程度是需要配合实际流量去调的不是越激进越好。如果遇到单请求独占大量资源导致其他请求饿死的情况就得做抢占。抢占策略很简单把低优先级请求的KV Cache块临时释放给高优先级请求被抢占的请求等有空间了再恢复。不过KV Cache一旦释放再恢复就得从头计算代价极高所以我一般只在内存实在不够时才开抢占平时宁可让高优先级请求排队也别随意破坏正在生成的请求进度。4. 常见问题与排查技巧实录走到这一章很多优化手段已经可以串起来了。但真正落地的时候测试和调优进程里一定会碰到几位“老朋友”显存OOM、KV Cache命中率低下、批处理冲突、量化后生成质量波动。我把自己踩过的坑和排查思路整理成一个速查表方便你按图索骥。4.1 显存OOM与内存碎片排查最常见的OOM原因一个是并发请求的数量超过KV Cache池上限另一个是KV Cache池碎片化。前者比较好查你只要盯住监控面板里的“当前KV Cache占用/池总量”这个指标就能定位后者就棘手了你会看到显存总量还很宽裕但申请一块连续缓存却失败了。排查碎片化问题我推荐两步走第一检查分配日志中的连续内存长度分布如果看到很多几十MB、几百MB的小空块碎片化基本实锤第二把缓存池的块大小改成更小的等分块因为小等分块更容易被离散分配和回收。做了这两步碎片问题会缓解大半。另一个容易忽略的坑是某些框架默认给KV Cache池预分配了固定上限而这个上限的默认值跟你的显存并不匹配你得到配置文件里手动调大而不是等到OOM再重启服务。4.2 KV Cache命中率低下与Prefix复用失效如果你是做对话服务共享KV Cache命中率应该是一个核心指标。我在一次优化中看到命中率只有3%从头排查发现请求里的系统提示词明明完全一样但框架按整个请求的Token做哈希匹配任何一点细微差异都会让哈希失效。而且Prompt里只要多一个时间戳、用户昵称共享直接报废。解决思路是把“请求级缓存”优化为“段级缓存”。就是说不用整个请求的Key去匹配而是把Prompt按语义或模板拆成多个固定片段每个片段单独缓存。系统提示词当成一个片段固定工具栏当成另一个片段。这样即使请求里带了动态信息只要公共部分被正确识别缓存就能生效。这个改动如果在PostProcess层做不涉及到内核落地很快。我调优后命中率从3%一路拉到60%以上Prefill阶段的总计算时间砍掉了一小半。4.3 批处理冲突与吞吐波动吞吐波动的来源之一是Dynamic Batching。打开动态调度后如果批次里既有超长请求又有超短请求长请求会持续霸占块索引短请求不断进出导致块表像开飞机一样急剧伸缩。我在监控里看到过KV Cache块分配次数每秒过千这就不是正常状态了。排查办法是把批处理策略从“长度无限制”改成“同长度段优先”。就是先把请求按长度分成几个档每档内优先成批不同档位之间再做抢占。如果某个档位短时间内请求量不够可以设置一个较小的等待窗口宁可等几十毫秒凑批也不要把万字符长度的请求和十几个Token的请求混编在一个批次。这个思路做下来之后P99延迟掉了约30%吞吐波动也变得平缓。最后提到模型量化这是我吃过最多亏的地方。KV Cache量化之后生成的质量出现波动第一反应往往是把量化精度调高但效果往往不理想。我后来发现问题出在异常值上某几个Head的Value分布特别极端拉低了整个Tensor的比例因子把正常数值压得过于粗糙。解决办法是单独把极端Head移除出量化范围或者直接做Per-Head量化。修完之后质量波动基本消失容量优势保住了。这个坑给我最大的教训是量化参数永远不要只看全局统计一定要按模块粒度单独检查。实际搞性能工程的经验告诉我Prefill-Decode分离调优和KV Cache优化不是一个可以在纯理论层面上“想清楚”的话题。必须拿真实模型、真实显存监控、真实负载测试去验证。我之前一个模拟项目里分别跑了四种状态基线方案、仅分页KV Cache方案、加INT8量化方案、加动态批次调度方案最终吞吐从基线的一倍多提升到接近三倍首Token延迟降到原来的三分之一但为了达到这个结果反复改配置、抓日志、压测的次数已经数不过来。中间还有一次因为量化精度设置过头生成结果几乎变成了乱码差点让我以为模型崩了。所以如果你正在做类似调优我给你三条实操心得第一不要一次性同时改所有参数每次只动一个变量否则出了性能回退你不知道是哪个环节惹的祸第二监控数据一定要分阶段打点Prefill和Decode的耗时要单独记录否则出了问题连瓶颈在哪个阶段都说不清楚第三尽早做容量规划在模型加载阶段就预留好KV Cache池的上限不要让在线做大流量时再动态扩缩那个过程本身就会拖垮性能。这篇笔记写到这里我自己也在过程中重新梳理了一遍之前的调优路径。如果后面有新版本的推理框架做出更大的改动我会再补一篇续集重点讲讲集群多卡场景下KV Cache的跨设备负载均衡。

相关新闻

Day 42:模型量化基础 — INT8/FP16

Day 42:模型量化基础 — INT8/FP16

今日目标:掌握模型量化的核心原理,理解对称量化与非对称量化,学会PTQ和QAT的区别,为端侧部署打好基础 预计阅读:12分钟 | 动手操作:40分钟一、为什么需要量化? 端侧AI的核心矛盾:模型…

2026/10/14 9:54:36 阅读更多 →
AI芯片缺陷检测黑盒难题:可解释性与工程落地实践

AI芯片缺陷检测黑盒难题:可解释性与工程落地实践

1. 当AI走进芯片车间,为什么老师傅还是不敢松手前阵子跟一位在芯片行业摸爬滚打十几年的老朋友吃饭,他跟我吐槽了一件事:公司花大价钱引进了一套AI辅助的缺陷检测系统,号称能自动识别晶圆表面的微米级瑕疵,准确率标称9…

2026/10/14 9:53:33 阅读更多 →
PS5多主机外设整合方案:HID映射、音频分离与SSD扩容实战

PS5多主机外设整合方案:HID映射、音频分离与SSD扩容实战

如果你手里有两台以上的PS5,或者你经常在客厅、书房、工作室之间搬游戏机,大概率遇到过这样的场景:手柄要重新配对,键鼠转换器插上没反应,SSD拆下来换到另一台主机上不识别,音频分离器在新机型上还多了一堆…

2026/10/14 9:53:33 阅读更多 →

最新新闻

ESXi 升级到 8.0 后 VM 快照删不掉?一篇讲透 “in progress“ 死循环的 3 种解法

ESXi 升级到 8.0 后 VM 快照删不掉?一篇讲透 “in progress“ 死循环的 3 种解法

本文适用版本:ESXi 7.0 U3 → 8.0 U2 升级场景(vSphere 6.7 升级也会遇到) 阅读时长:约 8 分钟 难度:⭐⭐⭐(操作不可逆,生产 VM 强烈建议先备份再动)一、为什么写这篇文章?最近私信里又有几位网友问:ESXi 7.0 升到 8.0 之后,VM 的快照怎么都删不掉,vSphere Client 里一直显示…

2026/10/15 2:48:27 阅读更多 →
ESXi ping 得通但连不上 vCenter?一篇讲透 hostd 假死的全套救法

ESXi ping 得通但连不上 vCenter?一篇讲透 hostd 假死的全套救法

本文适用版本:ESXi 7.0 U3 / 8.0 U2 / 9.0 GA 阅读时长:约 7 分钟 难度:⭐⭐(SSH 能进就能修,但要分清是 hostd 还是 vpxd 的锅)一、为什么写这篇文章?最近私信里又陆续收到几位网友问:ESXi 能 ping 通、SSH 也能进、DCUI 也正常,但 vCenter 里主机显示"未响应"或&q…

2026/10/15 2:48:27 阅读更多 →
前端XSS防御实战:xss-filters上下文转义库详解

前端XSS防御实战:xss-filters上下文转义库详解

简介:前端开源库-xss-filters是一份面向前端开发者与安全入门者的XSS防护工具源码包,聚焦于解决用户输入回显场景下的跨站脚本注入风险。资源共30个文件,以20个js源码与测试脚本为主体,辅以3个json配置、3个md说明文档&#xff0c…

2026/10/15 2:48:27 阅读更多 →
ESXi 装系统报错 “bootbank is corrupted“ 怎么办?一篇讲透三种根治方案

ESXi 装系统报错 “bootbank is corrupted“ 怎么办?一篇讲透三种根治方案

本文适用版本:ESXi 7.0 U3 / 8.0 U2 / 9.0 GA(三版统一报错,解决方案略有差异) 阅读时长:约 8 分钟 难度:⭐⭐⭐(需在 DCUI/物理机前操作,不建议生产机远程盲操作)一、为什么写这篇文章? 最近陆续有几位网友私信问同一个问题:装 ESXi 的时候跑到一半,屏幕突然卡住,报 bootbank…

2026/10/15 2:48:27 阅读更多 →
React Native position 定位详解:relative 与 absolute 实战指南

React Native position 定位详解:relative 与 absolute 实战指南

1. 为什么 position 定位值得单独拎出来讲做 React Native 开发的人,迟早都会在布局上栽跟头。Flexbox 那一套东西,flexDirection、justifyContent、alignItems三板斧抡完,大部分界面确实能搭出来。但总有一些场景,光靠 Flex 流式…

2026/10/15 2:48:27 阅读更多 →
从零开发聚合9大视频网站的桌面App:技术选型与发布运营复盘

从零开发聚合9大视频网站的桌面App:技术选型与发布运营复盘

前阵子我在一个技术交流群里发了句感叹:“现在做桌面应用,是不是有点逆潮流?”结果有个朋友直接回我:“你做一个有用的桌面工具试试,用户在乎的是好不好用,又不是你用什么平台。”我当时不以为然&#xff0…

2026/10/15 2:47:27 阅读更多 →

日新闻

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 阅读更多 →