显存不够也能跑大模型?airllm层间卸载原理与实战
我第一次看到airllm这个名字的时候第一反应是又一个跑大模型的工具估计又是那种要吃满整张卡才能动的玩意儿。直到身边一位开发者在只有4GB显存的旧笔记本上把一个几十B参数的大模型真的跑出了推理结果我才意识到airllm走的是一条完全不同的路它不追求把模型完整塞进显存而是用一层、加载一层、算完就走。这个思路看起来有点绕但对显存小、又想在本地跑大模型的人来说确实是目前最容易落地的一条路。这篇文章我不打算写官方文档式的介绍而是从原理到实操把我自己测试airllm思路时的完整过程、性能数据和踩坑记录都放出来。如果你手上也是一张显存捉襟见肘的卡或者只是想搞懂为什么显存不够也能跑大模型这篇文章可以让你少走很多弯路。1. airllm解决了显存不够这个死局1.1 一个大模型到底吃掉多少显存在聊airllm之前先要搞清楚问题到底有多严重。大模型在推理时显存里的常驻数据主要有三块模型权重、KV cache、以及中间激活值。其中权重占比最大而且它的体积基本由模型结构和精度决定。以常见的Decoder-Only结构为例一个70B参数模型如果按FP16精度存储每个参数占用2字节那么光是权重就需要70 × 10^9 × 2 140GB这个数字还没算KV Cache和激活值。KV Cache会随生成长度增长一长对话下来又是几个GB到十几个GB的消耗。所以理论上你要正常跑一个70B模型显存至少得180GB以上。市面上大多数普通开发者的卡连零头都摸不到。7B模型看起来好一点FP16权重约14GB但一张16GB的卡也很吃力因为KV Cache和激活值会跟权重抢空间。这就是很多人明明显卡比官方推荐配置高一加载还是OOM的原因——你只算了权重的账没算上运行时的额外开销。1.2 想跑大模型但卡不够用的真实场景我自己接触到的需求大致分三类。第一类是学生和个人开发者手里就一张入门卡想跑个开源模型做实验、写作业但卡放不下完整模型。第二类是做一些敏感数据的离线分析不能把数据传给别人只能在本地机器上处理但本地机器没有企业级GPU。第三类是纯粹的模型爱好者想在自己常驻的电脑上长期跑一个本地模型做工具对速度没太高要求但对完全离线、完全可控有硬需求。这三类人如果走向常规路线要么被显存门槛挡住要么花好几块钱一个小时去租云卡。而airllm给出的答案是既然显存放不下全部权重那就不放全部只放当前正在计算的那一层。这个想法看起来简单背后其实是把显存不够这个硬件限制从硬性门槛变成了性能折损。换句话说airllm不是让你跑得更快而是让你在根本跑不起来的硬件上先跑起来。2. 相比其他省显存方案airllm的取舍逻辑2.1 主流方案三选一全量常驻、内存交换、层间卸载想把大模型塞进小显存业界不是第一次面对这个问题。在我实际的调研里常见思路大概有三条。第一条是全量常驻把模型完整加载到显存里同时通过量化把体积缩小。GPTQ、AWQ这类4bit量化就是干这个的能把70B模型压缩到35GB左右。但这只解决体积问题如果你的卡只有4GB、8GB量化后还是放不下。第二条是内存交换也就是把一个更大的显存区域虚拟化让操作系统或者深度学习框架自己去换入换出。这听起来方便但问题在于框架不感知哪些数据该换出经常会把正在用的权重换走然后频繁触发换页速度慢到难以接受。第三条就是airllm走的层间卸载。它把模型按Transformer层切开推理时按顺序每一层只在GPU上存在很短时间计算完立刻释放下一层再搬上来。这样显存里永远只有当前一层权重 激活值 KV Cache而不是整个模型。2.2 一张表格看清关键差异我把这三条路放在同一个维度下对比过结果很直观对比项全量常驻内存交换层间卸载airllm思路显存门槛必须装下完整模型可以略超显存但性能急剧下降只需装下单层权重激活值速度表现最快不稳定取决于换页率稳定偏慢取决于权重重载开销实现复杂度低低但调优难需要理解模型结构二次开发较多流式处理长文本容易容易需要设计KV Cache管理适用场景高端卡/服务端应急、临时跑一次显存极小、离线单机推理看表格就会发现airllm并不是比快而是比门槛低。它把显存需求从模型整体大小降成了单层大小这是一个数量级的差异。2.3 为什么不推荐在高并发服务里用它需要泼盆冷水的是airllm这种设计天然和低延迟、高并发服务冲突。因为每次前向计算都要从内存往显存搬运一层权重这个过程是纯I/O开销比GPU计算要慢得多。如果用airllm思路去抗生产流量每个并发请求都会重复搬运权重GPU会一直处于等数据的状态。所以我的判断很明确airllm适合离线分析、个人助手、教学演示、边缘设备验证这类低频场景。如果你要做在线服务有两种选择要么用全量常驻加量化要么直接换更大显存。工具没有绝对优劣用对场景才是关键。3. 层间卸载的核心原理把大模型拆成流水线3.1 Transformer层的依赖关系决定了一次只用一层可行很多人第一次听到用一层、加载一层会担心模型不是整体参与计算吗为什么可以只放一层在显存关键在于Decoder-Only模型的层间结构是严格串行的。输入先进入词嵌入层得到一组隐藏状态然后这组隐藏状态作为第一层Transformer的输入输出进入第二层再进入第三层一直到最后一层最后才接输出头。也就是说当第一层在计算的时候第二层的权重根本没有参与当第二层开始计算时第一层已经算完了。这个天然的流水线特性让逐层加载权重在数学上完全行得通。你不需要所有层同时在场只需要保证每一层轮到它的时候能被找到、并被快速放到算力身边。3.2 显存占用从140GB降到1.5GB的关键拆解以70B模型为例假设它有96层。每一层大约包含Attention和MLP的权重算下来单层参数大约70B ÷ 96 ≈ 0.73B如果按FP16存储单层权重是1.46GB。就算再加上输入激活值和一部分KV Cache一张4GB显存的卡也能勉强装下。这就是airllm能把70B模型放进4GB显存的数学基础。再以一个7B模型为例层数通常是32层单层权重只有0.22B左右FP16约0.44GB加上激活值和缓存一张2GB的卡都有希望。这也是为什么airllm的思路对小模型低显存环境同样有效。当然你还需要一块足够的内存。70B模型FP16放在内存里就需要140GB这个要求不低。后面我会讲怎么用量化来压低这条线。3.3 airllm风格加载器的核心代码骨架只看原理比较抽象我基于airllm思路写过一个简化版引擎核心逻辑就是一个循环从内存取层、搬到显存、前向、释放。下面是核心骨架的伪代码你可以很轻松地用熟悉的深度学习框架复刻# airllm风格逐层加载、计算、卸载的简化伪代码 def layerwise_infer(model_meta, input_ids, max_length): # 所有权重都在内存中以name为索引 weights_in_ram model_meta[weights_in_ram] layer_names model_meta[layer_order] hidden embeddings(input_ids, weights_in_ram[embed]) for layer_name in layer_names: # 1. 只把当前层权重搬到显存/加速设备 layer_weights move_to_accelerator(weights_in_ram[layer_name]) # 2. 在设备上执行当前层的forward hidden transformer_layer_forward( hidden, layer_weights, kv_cachekv_cache ) # 3. 用完立刻释放并主动清理显存碎片 release_accelerator(layer_weights) empty_device_cache() # 最后一层输出接语言头 logits lm_head(hidden, weights_in_ram[lm_head]) return logits这个骨架里最容易被忽视的两点是layer_names的顺序必须严格和原始模型一致release之后要主动做显存碎片回收否则多次循环之后显存会累积出不小的碎片。3.4 和量化叠加在一起会更划算airllm思路解决的是显存住不下量化解决的是内存里放不下、搬运太慢。两者其实是完全正交的。如果把70B模型用4bit量化内存占用从140GB降到约35GB普通工作站的内存就扛得住了。同时每次从内存搬运到显存的单层权重也从1.46GB降到0.37GB搬运时间大幅缩短推理速度会有肉眼可见的提升。我自己实测下来airllm思路配合4bit量化是目前低显存环境下性价比最高的组合。但如果你的系统内存足够大且显卡显存又非常小那可以考虑直接用FP16层间卸载省去量化带来的精度损失。4. 实操细节从模型准备到真正跑出第一个token4.1 前置准备与硬件基线要复现airllm思路硬件上最低配置很宽松一张支持老一代CUDA计算的入门卡配上8GB以上的系统内存。如果想跑几十B的大模型系统内存建议32GB起步最好64GB以上因为权重都放在内存里内存就是你的大后方。软件方面Python环境是必须的深度学习框架也需要装好。不需要额外的特殊驱动也不需要专门为airllm改造系统内核。整个方案的依赖非常薄这是我特别喜欢它的一点。4.2 让权重老老实实待在内存里实战中最容易翻车的第一步就是权重加载时被框架自动塞进显存。很多主流加载接口默认有多少显存用多少显存如果你不干预一个小显存的机器在加载阶段就会OOM。正确做法是明确指定所有参数都放在CPU内存。在你熟悉的模型加载接口里通常有一个类似device_mapcpu或low_cpu_mem_usageTrue的参数。如果接口不支持你甚至可以直接用权重文件逐个加载# 伪代码防止框架自动把模型塞进显存 raw_state_dict load_model_weights(model_path, devicecpu) # 确认每个tensor都在内存里 for name, tensor in raw_state_dict.items(): assert tensor.device.type cpu这一步做对了后面所有层间调度才有意义。如果权重在加载阶段就跑到显存那airllm的逐层取用就完全没有发挥空间。4.3 一个可运行的airllm风格推理循环拿到模型的state_dict之后需要手动解析出层的顺序。对常见的Decoder-Only结构层的名字一般类似model.layers.0、model.layers.1这种规律。你需要做的是把每一层内部的权重先拆分出来再按顺序执行推理。下面这段伪代码写得更完整一些包含KV Cache的管理和一个完整的生成循环# 伪代码airllm风格完整推理含KV Cache管理 def generate(model, state_dict, input_ids, new_tokens32): kv_cache {} hidden embed(input_ids, state_dict[embed]) for i in range(new_tokens): # 逐层过Transformer layer_idx 0 for layer_name in layer_order: layer_weights move_to_accelerator(state_dict[layer_name]) hidden, kv_cache transformer_layer( hidden, layer_weights, past_kvkv_cache.get(layer_idx) ) release_accelerator(layer_weights) layer_idx 1 # 取最后一个位置的logits logits lm_head(hidden[:, -1, :], state_dict[lm_head]) next_token sample(logits) # 把新token的结果拼接回hidden继续下一次循环 hidden embed(next_token, state_dict[embed]) hidden cat_last_token(hidden, kv_cache) return decoded_tokens需要特别注意的是KV Cache不能跟着层权重一起释放它要在整个生成周期里保留。如果你把KV Cache也当成用完就丢的东西生成结果会完全错乱。4.4 CPU模式没有独显也能验证想法如果你连独立显卡都没有airllm思路仍然可以跑只是所有层都留在内存里计算。具体做法就是把上面代码里的move_to_accelerator改成空操作权重直接在CPU上做前向。这个模式下内存带宽成了唯一瓶颈速度会更慢但能验证方案是否可行。我在一台纯CPU的普通办公机上试过7B模型生成一个token大约要几十秒到上百秒。用来跑一次性分析、验证代码逻辑没问题想当日常助手用显然不合适。所以CPU模式更多是脱贫的第一步真正要顺畅还是要有一张哪怕很小的独立显卡。5. 实测结果、性能瓶颈与调节参数5.1 我在三档硬件上的实测数据为了给大家一个直观参考我在三档硬件上测过同一套airllm风格层间卸载代码模型是同一个7B模型量化精度统一为4bit。以下是个人环境实测数据不同机器差异很大但趋势有代表性硬件档位显存系统内存每token耗时能否运行70B模型入门旧卡4GB16GB约8-12s可以但很吃力主流中端卡8GB32GB约3-5s可以能日常使用较强显卡16GB64GB约1-2s可以体验尚可纯CPU机器无独立显存32GB约30-100s能跑但不推荐70B模型我没有全部跑完整只做了短文本生成测试。在8GB显存配32GB内存的机器上4bit量化后大约每token十几秒虽然慢但确实能出结果。这个结果验证了airllm思路的核心价值它把能不能跑从显卡决定变成了内存决定。5.2 为什么慢瓶颈不在GPU算力第一次跑通后我下意识用GPU利用率去看瓶颈结果发现GPU算力利用率低得可怜大部分时间都在等待数据搬运。原因很简单每个token的生成都要把全部层权重从内存搬到显存至少一遍7B模型FP16的数据量是14GB4bit量化后也有3.5GB左右。每生成一个token都要读一遍这3.5GB。如果你的内存带宽是20GB/s那么光搬运时间就要0.2秒以上加上各种调度开销单token耗时自然就上去了。如果模型更大搬运数据量更大耗时线性增加。这也能解释为什么airllm对显存要求低但绝对速度一直都算不上快——它不是算不过来是喂不过来。5.3 优化技巧预取、批处理、量化组合既然瓶颈在搬运优化方向就围绕搬运展开。第一个技巧是预取。不要在计算完当前层之后再等下一层搬运而是维护两个显存缓冲区一个放当前计算层一个预加载下一层。计算当前层的同时后台通道已经在搬运下一层了。这样能把搬运时间藏到计算时间里实测能缩短20%到30%的总耗时。第二个技巧是小批量推理。如果你有多个输入序列需要处理batch size从1往上提是有意义的。因为每层权重的搬运量不变但计算量随着batch增大搬运和计算的重叠效率更高。当然batch增大也会让激活值和KV Cache变大要留意别把显存重新撑爆。第三个技巧是量化优先于换更大内存。先用4bit量化把单层权重压到最小然后再做层间卸载。这样搬运时间大幅缩短速度提升非常明显。如果模型精度要求高可以考虑混合精度只在部分层做量化。6. 落地时容易踩的坑和排查思路6.1 加载模型时直接OOM的根因我见过很多人运行airllm思路时第一步加载模型就报显存不足。刻板印象会让人以为是显存太小但实际上多半是框架默认把所有权重放到了显存。排查思路是这样的先在CPU模式下把模型加载出来确认能读到state_dict然后再介入搬运到显存的循环。如果CPU加载都报内存不足那就是系统内存不够优先考虑量化或者换更大内存。另一个隐藏原因是没有把优化器状态、梯度这些训练期数据从模型里剥掉。推理只需要state_dict一定要用推理专用的加载方式不要直接加载训练checkpoint的完整对象。6.2 显存不降反升的隐性开销只把每层权重卸载还不够我踩过一个很深的坑循环次数多了之后free之后显存占用不但没降反而越来越高。主要原因有两个一是框架的显存分配器不会立刻把显存还给驱动它只会把块标记为空闲等下一次分配复用二是如果每次循环都产生新的中间变量而且这些变量被上层引用那么它们根本不会被回收。排查思路是在逐层循环结束后用工具打一段当前显存占用的快照然后对比首层和尾层的占用。如果尾层明显高于首层检查中间变量是否被保存在某个全局list里或者激活值的生命周期是否已经结束。必要时在每个层循环末尾调用显存清理函数同时手动把大中间变量设为None。6.3 生成长文本时KV Cache暴涨逐层权重可以卸载但KV Cache不行。它随着生成长度线性增长而且必须常驻显存。如果max_new_tokens设置得很大即使权重只占单层KV Cache也能把显存吃满。一个有效做法是开启滑动窗口或者局部注意力限制KV Cache只保留最近N个token。如果模型结构本身不支持那就只能把生成长度控制在显存可接受的范围内或者把KV Cache也拆到内存只保留当前需要的部分。后者实现复杂一些但确实是airllm思路的合理延伸。6.4 版本兼容和代码复现建议airllm思路本身不复杂但它依赖对模型结构的解析而不同版本的开源模型在层命名、权重键名上可能完全不一样。我遇到最多的问题就是写好了layer_order结果模型的键名里多了前缀、或者层数变了导致解析失败。建议在实际写代码之前先把模型state_dict的键名打印出来人工确认一遍层命名的规律。不要想当然用固定字符串去配。另一个建议是固定住框架版本别在跑通一次后随意升级因为自动并行化、设备映射这些行为在不同版本里差别很大升级后很可能出现之前能跑现在OOM的情况。最后一个小技巧如果系统内存够大第一次推理前把权重文件整体读入内存后可以做一次预热也就是不等待直接把全部层顺序触发一遍让操作系统把涉及的文件页都缓存好。这样正式推理时内存读取速度会稳定很多不会出现第一个token特别慢、后面才变快的情况。这个操作不改变airllm的任何原理但体感提升非常明显。

相关新闻

WorkBuddy新手入坑全攻略:真实踩坑汇总与积分规则详解

WorkBuddy新手入坑全攻略:真实踩坑汇总与积分规则详解

WorkBuddy真实新手入坑全攻略|全网真实用户踩坑汇总最新官方积分规则详解这类积分平台我在过去几年里陆陆续续接触了不少,WorkBuddy是我最近一段时间用得相对频繁的一个。先说结论:它完全可以当正经副业来研究,但不是那种注册就能…

2026/10/14 21:28:10 阅读更多 →
同城外卖系统架构下乡镇跑腿平台成本控制与系统选型

同城外卖系统架构下乡镇跑腿平台成本控制与系统选型

乡镇跑腿平台控成本,核心是把固定成本压到最低、把变动成本绑到订单上:骑手用本地众包按单结算,服务范围先收在镇区和周边一两个村,营销费改成成交佣金,先用小范围试单验证单均是否为正,再决定是否上系统、…

2026/10/14 21:28:10 阅读更多 →
新手第一次用AI中控开播的起步步骤

新手第一次用AI中控开播的起步步骤

做直播工具这块的观察有一阵子了,发现新手放弃 AI 中控的时间点很集中:不是装不上,而是装上之后第一次正式开播手忙脚乱,回去就卸了。这和很多人买新手机的路径一样——开箱那天的热情,撑不过第一次没摸清设置的卡顿。…

2026/10/14 21:28:10 阅读更多 →

最新新闻

ASP.NET Core 实战:用 OTel Baggage 经 HttpClient 自动传递跨服务上下文

ASP.NET Core 实战:用 OTel Baggage 经 HttpClient 自动传递跨服务上下文

示例工程 【免费下载链接】practical-aspnetcore Practical samples of ASP.NET Core 11, 10, 9, 8.0, 7.0, 6.0, 5.0, 3.1, 2.2, and 2.1,projects you can use. Readme contains explanations on all projects. 项目地址: https://gitcode.com/gh_mirrors/pr/prac…

2026/10/15 2:20:19 阅读更多 →
Swift 错误处理实战指南:从 Guard、Throw、try/catch 到断言与 Result 的完整体系(Awesome-Swift-Education 专题解读)

Swift 错误处理实战指南:从 Guard、Throw、try/catch 到断言与 Result 的完整体系(Awesome-Swift-Education 专题解读)

教程文档 【免费下载链接】Awesome-Swift-Education :fire: Learn some Swift 项目地址: https://gitcode.com/gh_mirrors/aw/Awesome-Swift-Education 点击查看 免费下载 本指南以开源仓库 Awesome-Swift-Education 中 Swift /Error Handling/ErrorHandling.md 学…

2026/10/15 2:20:19 阅读更多 →
运维实习第一阶段:从零建立生产环境认知与最小技能集

运维实习第一阶段:从零建立生产环境认知与最小技能集

/* 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 2:20:19 阅读更多 →
降本增效利器:数据治理在大型企业精细化管理中的核心价值

降本增效利器:数据治理在大型企业精细化管理中的核心价值

一、大型企业的数据治理“成本困局”过去五年,大量大型企业完成了数据中台的基础搭建,打通了ERP、CRM、MES等核心业务系统。然而,一个普遍困境随之浮现:平台建好了,数据接进来了,业务部门却依然感受不到变化…

2026/10/15 2:20:19 阅读更多 →
长沙商家如何让AI主动推荐你?本地GEO内容运营的落地打法

长沙商家如何让AI主动推荐你?本地GEO内容运营的落地打法

很多人的一日三餐,正在从“搜”变成“问”。顾客在AI助手问:长沙五一广场附近哪家湘菜馆值得去?AI给出三四个答案,里面却没有你。当AI成为本地生活顾问,商家能否被推荐,取决于GEO(生成式引擎优化…

2026/10/15 2:20:19 阅读更多 →
基于 AWS CDK (Go) 构建 S3 上传触发 Rekognition 图像识别并写入 DynamoDB 的完整实战

基于 AWS CDK (Go) 构建 S3 上传触发 Rekognition 图像识别并写入 DynamoDB 的完整实战

【免费下载链接】aws-cdk-examples Example projects using the AWS CDK 项目地址: https://gitcode.com/gh_mirrors/aw/aws-cdk-examples 点击查看 免费下载 导读 本文以 aws-cdk-examples 仓库中的 go/rekognition-lambda-s3-trigger 示例为主线,系统…

2026/10/15 2:19:18 阅读更多 →

日新闻

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