大规模机器学习实战:分布式并行核心技术与工程优化指南
1. 大规模机器学习到底在解决什么问题先抛一个很多人会问的问题天天听人说“大规模机器学习”“分布式训练”“数据并行”这些词到底和普通机器学习有什么本质区别我见过不少同学一开始以为“大规模”就是“数据多”觉得自己用单机也能跑几十GB数据是不是也算大规模了其实不是。这里面的核心分界线不是数据总量的多少而是一个很现实的问题单台机器能不能装得下数据和模型、能不能在可接受的时间内完成训练。打个比方。你开一家小吃店自己一个人洗菜、切菜、炒菜、收银一天能出200单这叫小作坊模式。但如果你想做到一天2万单问题就不是“菜多洗一会儿”那么简单而是整个运作方式都得变你需要多个工位、多个厨师、标准化的流程、还有调度的人。大规模机器学习本质上干的就是这件事——把一家小吃店升级成中央厨房。具体来说大规模机器学习通常涉及三样东西大规模数据TB级甚至PB级、大规模模型几十亿到几千亿参数、大规模计算资源几十张卡到几万张卡。其中任何一个达到规模化都会带来全新的工程挑战。而这些挑战并不是“多买几台服务器”就能解决的它涉及算法、系统、网络、存储的协同设计。所以这篇文章我想从一个实践者的角度把大规模机器学习涉及的几个核心问题、常用手段和真实工程中会遇到的事情讲清楚。不管你是学生、刚转行的工程师还是已经在做模型训练但想系统了解这块的开发者这篇文章应该都能给你一张比较完整的地图。2. 从单机到分布式三个躲不开的问题要理解大规模机器学习先要理解为什么“直接变大力气”行不通。把训练从单卡扩展到多卡第一反应是“并行”。但并行这件事一上来就会碰到三个互相纠缠的问题。2.1 算力问题单卡算不动怎么办参数量大了之后单张GPU卡根本放不下模型。一张主流的数据中心GPU显存也就80GB左右而一个大模型的参数加上优化器状态、梯度动辄需要几百GB甚至上TB的内存。这不是“多等一会儿”的问题是物理上放不下。解决思路很直接把一个模型拆开放到多张卡上。这就是模型并行的由来。但怎么拆是个学问。拆得不好卡与卡之间要频繁交换数据通信开销比计算还大跑起来反而比单卡更慢。2.2 数据问题喂不饱计算单元如果模型还能塞进单卡比如BERT这种亿级参数的模型那么扩大规模的主要矛盾就是数据吞吐。一张卡算得快但CPU读磁盘、预处理数据的速度跟不上GPU就会饿肚子利用率上不去。这时候需要数据并行把一份大数据集切成很多份每个计算节点拿一份各自算各自的算完再互相同步结果。数据并行是工程上用得最多、性价比最高的并行方式但它也有自己的麻烦——同步代价。2.3 通信问题同步比计算还贵数据并行最大的坑在于每个节点算完自己那一批数据之后需要把梯度汇总起来更新完模型参数再开始下一轮。这个过程叫梯度同步。节点越多同步需要的通信量越大。用一个简单的计算来说明。假设模型有1亿个参数每个梯度是4字节的浮点数那么一次全量梯度同步就要传输400MB数据。如果模型有100亿参数一次同步就是40GB。现实中网络带宽通常只有10Gbps到25Gbps算下来同步一次就需要几十秒钟。而模型在一个batch上的计算可能只需要几秒钟。算力还没吃饱通信已经把时间吃光了。所以说到底大规模机器学习系统设计本质上是在算力、数据、通信三者之间找平衡点。这也是为什么后面讲到的各种并行策略、混合精度、梯度压缩都是冲着这个平衡去的。3. 主流的规模化手段数据并行、模型并行与混合并行前面提到两类并行思路。实际工程中没有哪一招是万能的基本都是组合着用。这一节把几种最重要的并行方式讲透。3.1 数据并行最朴素的扩展方式数据并行的思路很朴素大家用同一个模型各自吃不同的数据算完梯度后汇总再同步更新模型。具体做法是每个进程或者每张卡都保存一份完整的模型副本训练时把global batch切分成多个mini batch分发下去。每个节点前向传播、反向传播算出梯度之后用AllReduce操作把所有节点的梯度做平均然后各自用平均后的梯度更新自己的模型副本。数据并行实现简单、效果直接适合模型不大、数据量大的场景。它在代码层面几乎不需要改模型结构是性价比最高的起步方式。但它的限制也很明显模型太大放不进单卡的时候就玩不转另外同步通信成本会随节点数线性增长。工程上有几个优化方向。一是梯度累积在本地多算几个batch再同步一次降低通信频率二是梯度压缩只传输量化后的梯度减少通信量三是异步训练一些节点不等其他节点直接更新参数。异步训练收敛不稳定严格来说需要额外调参实战中用的不如同步模式多。3.2 模型并行塞不下就拆开模型并行的出发点完全不同既然一张卡放不下整个模型那就把模型拆成多份。拆法主要有两种。按层切分流水线并行把网络的不同层放到不同卡上。比如一个12层的Transformer前4层放卡1中间4层放卡2最后4层放卡3。数据从卡1流到卡2再到卡3像工厂流水线一样。好处是每张卡只需要保存一部分层显存压力大幅减少坏处是存在空闲时间——卡1还在算第1个batch的时候卡2在等数据利用率天然有损耗。后来有人提出把batch再切片、让多个batch在流水线里首尾相接以提升利用率这就是流水线并行中常用的小batch切分技巧。按矩阵切分张量并行把某一层的权重矩阵按行或按列拆开分到不同卡上计算时通过AllReduce汇总结果。这种做法通信量更大但可以突破单卡显存极限适合超大模型比如几千亿参数的那种就是张量并行配合流水线并行一起用的。3.3 混合并行真实场景的常态现实中很少只用一种并行方式。比较经典的组合是数据并行 流水线并行 张量并行。比如一台8卡机器4张卡组成一组做张量并行两组之间做流水线并行然后多台机器之间再做数据并行。这么组合的底层逻辑是GPU之间的通信带宽远高于跨机器的网络带宽。所以通信最频繁的拆分方式张量并行放在同一台机器内部通信不频繁的拆分方式数据并行放在机器之间。在混并行体系里显存分配也是门学问不能只盯着模型权重。训练时显存占用大头包括模型参数、参数的梯度、优化器状态比如Adam要存两个动量项、前向传播中的中间激活值。大规模模型训练中激活值占用往往比模型本身还大。所以后来出现的激活重计算技术就是牺牲少量计算量换显存——前向传播时不保存中间激活值反向传播需要时再重新算一遍。这个技巧在超大规模训练中几乎是标配。提示工程上判断一个训练系统设计得好不好就看它能否在“算力、显存、通信、稳定性”四者之间找到可接受的平衡点。单一指标最优没有意义短板才是瓶颈。4. 框架选型与参数配置实操层面的关键决策理论讲完进入实操。大规模机器学习不是理论推演是在框架上一步步配出来的。这里聊聊框架选型和几个关键参数的设置逻辑。4.1 三个层面的框架选择如果用一句话总结现在的生态大模型训练首选专用分布式框架普通模型训练用通用深度学习框架加分布式扩展底层接口自己写的情况越来越少。常见的分布式训练框架和定位可以这样分通用深度学习框架的分布式能力自带分布式训练模块API友好适合中小规模训练场景支持数据并行和简单的模型并行。优点是文档全、社区大、上手快。大模型训练框架专门为超大模型设计的内置张量并行、流水线并行、混合精度、激活重计算等能力很多大模型训练都用这类方案。底层通信库分布式训练的地基负责GPU之间的数据传输。绝大多数上层框架都建立在它之上。对于大多数团队来讲没有必要自己封装分布式通信逻辑。选择哪个框架取决于你的模型规模和团队的技术栈。一般规律是模型在10亿参数以下通用框架的数据并行就够了10亿到100亿需要考虑流水线并行和混合精度100亿以上建议直接上专用大模型训练框架。4.2 几个关键参数的理解实操中会碰到很多参数每个参数背后都是有讲究的。批次大小Batch Size数据并行时总批次大小 单卡批次大小 × 并行卡数。如果单卡批次是32用了32张卡总批次就是1024。注意批次变大会影响收敛精度可能需要相应调整学习率。常规经验是学习率随批次大小线性或平方根缩放。梯度累积步数如果显存放不下大batch可以用梯度累积模拟。累积步数 × 单步batch 等效batch。但它不是免费的——累积期间参数不更新等于训练步数拉长需要权衡。混合精度用FP16计算、FP32存储能省将近一半显存速度也会提升。但FP16的数值范围小容易出现梯度下溢。所以现在通常用BF16它和FP16一样省显存但指数范围和FP32一致在大模型训练中表现更稳。分布式优化器状态切分数据并行时每张卡其实都保存了完整的优化器状态。对于大模型这个状态比模型本身还大。于是出现了相关的显存优化策略把优化器状态切成多份每张卡只保存自己负责的那一份更新完再用AllReduce把完整参数同步回去。这个技术在多个主流框架中都有实现用起来也相对透明但需要你把优化器接管逻辑交给框架自行处理。4.3 启动方式从单卡到多卡的代码改动用比较流行的框架做数据并行代码改动其实不大。核心就两步初始化分布式环境然后用分布式数据并行包装模型。下面给一个最小示例展示数据并行训练的基本骨架import torch import torch.distributed as dist import torch.multiprocessing as mp from torch.nn.parallel import DistributedDataParallel def train_worker(rank, world_size, model, dataset): # 初始化进程组这里的通信协议可以是TCP或共享显存等 dist.init_process_group(backendnccl, rankrank, world_sizeworld_size) # 数据并行包装 ddp_model DistributedDataParallel(model, device_ids[rank]) # 分布式数据采样器保证每个进程拿到不同的数据分片 sampler torch.utils.data.DistributedSampler(dataset, num_replicasworld_size, rankrank) dataloader torch.utils.data.DataLoader(dataset, samplersampler, batch_size32) for epoch in range(10): sampler.set_epoch(epoch) # 防止每个epoch的数据分片完全一致提升泛化 for batch in dataloader: # 常规的前向、损失、反向、更新流程 loss train_step(ddp_model, batch, rank) if rank 0: print(fepoch {epoch}, loss: {loss.item():.4f}) # 训练结束后销毁进程组 dist.destroy_process_group()这段代码看起来和单机训练差别不大但背后框架已经帮你做了梯度同步。真正写起来还有一个坑是保存模型时要注意多个进程会同时写文件通常只在主进程rank 0上保存避免写坏。启动多卡训练一般不用手动写多进程代码框架提供的启动器可以搞定。比如用启动脚本指定总进程数每张卡跑一个进程。5. 真实工程中的性能瓶颈与排查实录理论说再多真正跑起来才会发现大规模机器学习的难点在工程细节里。这里把我踩过的一些坑和排查思路分享出来。5.1 GPU利用率低最先要查的问题训练时发现GPU利用率只有30%或者忽高忽低这个现象最常见的根源是数据加载太慢。GPU算完一个batch只要1秒CPU处理数据用了2秒GPU就干等着。排查思路先想一下数据管线数据是不是存储在远端的网络磁盘上读取会不会成为瓶颈预处理逻辑是不是在CPU上做太重图片解码、Tokenizer、数据增强这些如果都在CPU单线程里做很容易拖后腿。解决办法一是把预处理结果提前缓存到本地SSD或内存二是用多进程数据加载多个进程并行读数据和预处理三是检查DataLoader的num_workers参数是不是设得够大。一个经验法则num_workers一般设为CPU核心数的1到2倍但也不是越大越好过大会增加进程切换和内存拷贝开销。如果数据加载没问题那就看通信。试想一下两个GPU之间同步梯度需要时间如果计算量小、通信量大GPU也会有大量时间在等待。这个时候需要检查是否频繁做了小数据量的梯度同步必要时开启梯度累积降低同步频率。5.2 内存溢出OOM不是只有模型才占显存跑大规模训练显存OOM几乎是必经之路。很多人以为OOM就是模型太大其实大多数情况下是中间激活值爆了。一个Transformer模型batch size32、序列长度1024、隐藏维度2048前向传播过程中保存的激活值可以达到几十GB。如果你只把模型参数估算了一下发现“能放下”但一跑就OOM十有八九是激活值的问题。解决手段优先级是这样排的开启激活重计算激活值不保存反向时重新计算前向这是最常见、最有效的一招代价是训练速度慢10%~20%左右。减小单卡batch size配合梯度累积保住总batch大小。检查是否有不必要的中间张量被保存在计算图里比如调试信息、无关输出。开启混合精度FP16或BF16能直接砍半显存占用。最后才是换更大的卡显存问题不能总指望硬件堆。5.3 Loss不下降先怀疑收敛策略再怀疑代码大规模训练loss不下降或者下降后突然爆炸常见原因有这么几类按概率排序学习率设置不合理批次变大后学习率没调模型发散。检查学习率在不同批次下的缩放逻辑。数据顺序问题数据在各进程间分配不均匀或者某些进程拿到了噪声特别大的数据。分布式训练中要确保每个进程的数据分布大体均匀DistributedSampler的shuffle逻辑要仔细检查。混合精度下的数值问题如果用的是FP16梯度下溢会导致不更新检查梯度统计值是否出现大量零值。通信损坏多机训练时网络不稳定导致某些节点的参数没有同步成功loss会周期性异常。这时候可以检查各节点的梯度范数看是不是某张卡的梯度和大家差很多。一个实用的排查思路是先在单卡上把小规模数据跑通确认代码逻辑没问题再逐步加规模。规模翻倍一处就对照检查一处不要一次性把所有并行策略全部打开否则出了问题根本定位不了。5.4 常见问题速查症状常见原因优先排查方向GPU利用率低CPU预处理慢、数据IO卡顿缓存数据、调大num_workersGPU利用率波动大通信等待、负载不均检查网络带宽、启用梯度累积显存OOM激活值太大、参数太大激活重计算、混合精度、减小batch多卡loss比单卡差学习率未调整、数据分布不均缩放学习率、检查数据分片逻辑训练产出NaN学习率过大、混合精度数值下溢降低学习率、换BF16、加梯度裁剪保存模型文件损坏多进程同时写文件只在主进程保存6. 规模化之后还要想清楚的事最后聊几个容易忽略但很重要的点这些往往决定一个大规模训练任务最终能不能顺利落地。6.1 故障恢复不是可选功能大规模训练跑到一半节点挂了怎么办几十张卡跑了一个星期的任务因为一张卡的故障全部重来这是不可接受的。所以工程上必须有断点续训机制。核心是周期性保存checkpoint保存内容包括模型参数、优化器状态、当前epoch和step、学习率调度器的状态甚至数据采样器的随机种子。保存频率权衡训练时间一般每几百步存一次。这样即使节点故障可以从最近的checkpoint恢复损失最多几百步的计算量。另外要注意保存checkpoint本身也有耗时模型大了写磁盘也慢。用异步保存可以避免阻塞训练。最坏情况会丢失最近一次保存到当前之间的训练进度但总比重头跑要好得多。6.2 弹性扩展与成本控制在实践中训练任务本身往往只是一部分更麻烦的是资源管理。你需要多少卡训练多久排队资源的时间有多少调度系统是否支持队列和优先级一个实际考量买卡还是租卡。短期项目一般选租用弹性扩缩容用完即走成本可控。长期项目可以搭私有集群但电工、冷却、运维、监控样样都要有人管。很多人低估了后者的隐性成本。6.3 数据质量决定上限大规模机器学习的上限最终还是由数据质量决定的。计算资源可以堆模型可以越大越强但喂进去的数据如果是脏的模型再大也学不到好东西。在大规模场景下数据清洗本身也是一套工程体系去重、过滤低质内容、处理标签噪声、保证类别均衡。这部分的投入产出比往往比调模型结构高得多。我见过不少团队花几周时间在大模型结构上折腾实际效果不如花两天清洗一遍训练数据提升明显。写在最后大规模机器学习听起来很高深拆开来看一个模型加上一群并行策略本质就一句话怎么把一堆计算资源组织起来高效地训练一个更大的模型同时不被通信、显存、稳定性这些工程问题拖死。在我实际操作中的体会是不要一开始就追求把所有并行方式都用上。先用数据并行把小规模数据跑通理解每一步的瓶颈在哪里再有针对性地引入模型并行、混合精度、激活重计算等手段。每一步加一个变量观测一个效果这样你的系统会始终处于可控状态。另外一个很实用的小技巧在跑大规模训练之前先用一个小模型、小数据量做一次“干跑”把整个训练流程、checkpoint保存、恢复流程都走一遍。等正式大规模任务启动后你会少踩至少一半的坑。这个习惯我一直保留每次都能省下大量排查时间。

相关新闻

安全服务数智化转型:从告警淹没到自动化运营的落地路径

安全服务数智化转型:从告警淹没到自动化运营的落地路径

安全服务数智化转型,这几年是安全圈子里频率最高的词之一,也是真正做起来才知深浅的一件事。我在多个安全服务项目里泡过,看过团队被海量告警淹没的疲惫,也深度参与过从零搭建安全运营平台、把整个安全服务流程推上自动化轨道的全…

2026/10/16 4:30:21 阅读更多 →
大规模机器学习与分布式训练:并行策略、混合精度与工程实战

大规模机器学习与分布式训练:并行策略、混合精度与工程实战

1. 什么才算真正的“大规模机器学习”很多人一听到“大规模机器学习”这个词,第一反应是“用很多数据训练一个模型”。这个理解不算错,但远远不够。我见过不少团队,手里攒了几千万条样本,觉得这就是大规模了,结果一上分…

2026/10/16 4:30:21 阅读更多 →
视频转可编辑PPT:语音识别、大模型提炼到渲染的完整实操流程与避坑指南

视频转可编辑PPT:语音识别、大模型提炼到渲染的完整实操流程与避坑指南

视频变PPT这个需求,做科研、做教学、做汇报的人都懂——你手头有一段特别关键的讲解视频,可能是某课题组的学术报告录像,也可能是自己录的网课回放,或者是一场行业会议的演讲视频。你需要把里面的核心内容整理成一份能发给别人、能…

2026/10/16 4:30:21 阅读更多 →

最新新闻

Coder 平台深度解析:环境即代码与云端开发环境搭建指南

Coder 平台深度解析:环境即代码与云端开发环境搭建指南

1. 从“coder”这个标题说起:它到底指什么“coder”这个词,放在今天的技术语境里,含义比五年前宽泛了太多。早些年,它基本就是“写代码的人”的代称,跟 programmer、developer 混着用。但现在你搜“coder”&#xff0c…

2026/10/16 5:08:31 阅读更多 →
带权区间调度问题详解:从贪心失效到动态规划最优解

带权区间调度问题详解:从贪心失效到动态规划最优解

1. 先说这道题的含金量算法设计与分析课程里,习题6.3这种编号,往往卡在一个很微妙的位置——前几章刚讲完分治和贪心,后面紧接着就是动态规划,而6.3恰好就是让你把前两种思维揉碎了再重新拼起来的转折点。我当年做这道题的时候&am…

2026/10/16 5:08:31 阅读更多 →
SVM与神经网络工程选型决策指南:小样本、低延迟、高可解释场景实战

SVM与神经网络工程选型决策指南:小样本、低延迟、高可解释场景实战

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

2026/10/16 5:08:31 阅读更多 →
基于MP2642GR-Z与dsPIC30F4013的2S电池均衡设计与实现

基于MP2642GR-Z与dsPIC30F4013的2S电池均衡设计与实现

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

2026/10/16 5:08:31 阅读更多 →
2020团体程序设计天梯赛复盘:从模拟到压轴的易错点全解析

2020团体程序设计天梯赛复盘:从模拟到压轴的易错点全解析

2020年那届团体程序设计天梯赛,我是真没想到自己最后会坐在电脑前,以线上方式打完全程。更没想到的是,比赛结束后对照榜单复盘,我发现自己丢的分里,有将近三分之一不是"不会做",而是"会做但…

2026/10/16 5:08:31 阅读更多 →
C++十进制转十六进制:从手写算法到标准库全解析

C++十进制转十六进制:从手写算法到标准库全解析

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

2026/10/16 5:07:31 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

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

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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/15 9:49:14 阅读更多 →