PyTorch深度学习实战:从动态图原理到训练部署全解析
1. 为什么“PyTorch”这三个字值得单独拎出来聊如果你在AI圈子里待过一阵子会发现一个很有意思的现象大家聊模型、聊论文、聊数据集的时候往往一笔带过框架好像框架只是一个“默认存在”的东西。但真正上手做过项目的人心里都清楚从数据加载到模型训练再到部署上线框架选型几乎决定了你后面几个月的心情是舒畅还是崩溃。PyTorch就是这样一个被反复讨论、反复比较、又被大量项目验证过的深度学习框架。我最早接触PyTorch是在一个图像分类的小项目上当时手里只有一张消费级显卡数据量也不算大任务是把几千张图片分成十几个类别。那时候试过别的方案配置环境、定义计算图、调试梯度每一步都像在走迷宫。换成PyTorch之后最直观的感受是“代码写起来像在写普通的Python”动态图机制让调试变得非常自然你可以在任意位置打印张量、打断点、改逻辑不用先编译一整张静态图再跑。这个体验上的差异对于需要快速迭代实验的人来说几乎是决定性的。这篇文章想做的事情很具体把PyTorch这个标题背后真正值得展开的东西讲透。它是什么、能做什么、适合谁、核心机制怎么理解、实操中怎么搭环境、怎么组织训练流程、遇到问题怎么排查。我会尽量用从业者之间交流的口吻把那些文档里不会明说、但实际项目中一定会踩到的细节补上。无论你是刚入门想找一个靠谱的起点还是已经用过一段时间想系统梳理一遍下面这些内容应该都能对上你的需求。2. PyTorch到底解决了什么问题2.1 从“写模型”到“调模型”的重心转移深度学习项目里真正花时间的地方往往不是定义网络结构而是反复调整数据管道、损失函数、学习率策略、批次大小这些细节。PyTorch的设计哲学很明确让研究者把精力放在实验逻辑上而不是框架本身的约束上。它的动态计算图意味着每次前向传播都是即时构建的你可以根据运行时的条件动态改变网络行为比如在某些批次里跳过某个分支、根据输入长度调整循环次数。这种灵活性在自然语言处理和强化学习里尤其重要因为序列长度和状态转移往往不是固定的。相比之下静态图框架需要你先定义完整的计算图再执行虽然有利于图优化和部署但调试成本高。PyTorch后来也引入了TorchScript和编译模式来兼顾部署需求但它的核心体验始终是“先跑起来再优化”。这个取舍背后是对研究流程的深刻理解大部分实验是失败的快速失败比一次成功更重要。2.2 生态位的形成从研究到生产的连续谱PyTorch另一个被低估的优势是生态的连贯性。你在研究阶段用torch.nn定义的模型可以通过torch.jit.trace或torch.compile逐步过渡到推理优化数据加载用DataLoader和Dataset抽象换数据集只需要改几行训练循环用标准的optim和lr_scheduler组合迁移到分布式训练时改的是启动方式而不是模型代码。这种“同一套代码从实验走到上线”的能力减少了很多重复劳动。我见过不少团队在项目初期用PyTorch做原型后期因为性能需求想换框架结果发现迁移成本比预想的高得多最后干脆留在PyTorch里做优化。这说明它的生态已经足够覆盖大多数场景除非有非常特殊的部署约束否则没必要为了换而换。2.3 适合谁从学生到工程师的通用工具PyTorch的入门门槛相对友好但它的深度也足够支撑复杂项目。对于学生和研究者它的动态图和Python原生风格让实现新想法变得直接对于工程师它的分布式训练、混合精度、量化工具链已经相当成熟对于想转行进入AI领域的人PyTorch的社区资源和教程密度是最高的那一档。可以说只要你打算认真做深度学习相关的开发PyTorch都是一个值得投入时间掌握的技能。3. 核心机制拆解张量、自动求导与动态图3.1 张量一切计算的基本单元PyTorch里的张量Tensor和NumPy的ndarray很像但多了两个关键能力可以在GPU上运行以及支持自动求导。创建一个张量的方式很直观import torch # 从列表创建 a torch.tensor([[1.0, 2.0], [3.0, 4.0]]) # 创建全零、全一张量 b torch.zeros(2, 3) c torch.ones(2, 3) # 创建随机张量 d torch.randn(2, 3) # 指定设备和数据类型 e torch.tensor([1, 2, 3], dtypetorch.float32, devicecuda)这里有个实操细节torch.tensor会复制数据而torch.as_tensor在数据类型和设备匹配时可能共享内存。如果你在处理大规模数据这个区别会影响内存占用。另外torch.from_numpy创建的张量与原始NumPy数组共享内存修改一个会影响另一个用的时候要小心。张量的形状操作是日常高频动作。view和reshape都能改变形状但view要求内存连续reshape更灵活但可能触发复制。permute和transpose用于维度换位squeeze和unsqueeze用于增删维度。这些操作在写数据管道和自定义层时几乎每天都会用到建议多练几遍形成肌肉记忆。3.2 自动求导让梯度计算自动化PyTorch的自动求导机制建立在autograd模块上。当你对一个张量设置requires_gradTrue所有基于它的运算都会被记录形成一张动态的计算图。调用.backward()时梯度会沿着这张图反向传播结果存在各个张量的.grad属性里。x torch.tensor([2.0, 3.0], requires_gradTrue) y x ** 2 3 * x 1 z y.sum() z.backward() print(x.grad) # 输出 dz/dx 2x 3 [7.0, 9.0]这里的关键理解是计算图是在前向传播过程中动态构建的每次迭代都会重新构建。这意味着你可以在循环里根据条件改变计算路径比如for i in range(10): if i % 2 0: y x * 2 else: y x * 3 y.sum().backward() # 每次的图都不一样这种灵活性是动态图的核心价值。但也要注意每次backward()后梯度会累积所以训练循环里通常要调用optimizer.zero_grad()来清空。如果忘记这一步梯度会越加越大训练很快发散。这是新手最常见的错误之一。3.3 动态图与静态图的取舍动态图Eager Mode是PyTorch的默认模式优点是直观、易调试、支持Python控制流。缺点是每次执行都要重新解释性能上不如静态图优化充分。为了兼顾性能PyTorch提供了torch.jit.script和torch.jit.trace两种方式把模型转成静态图表示以及torch.compile在运行时做图优化。选择哪种模式取决于阶段研究和调试阶段用Eager Mode享受灵活性和可调试性部署和推理阶段用TorchScript或编译模式追求吞吐和延迟。我个人的经验是不要过早优化先把模型跑通、指标调好再考虑图优化。很多项目在Eager模式下已经能满足性能要求强行上静态图反而增加复杂度。4. 环境搭建与版本选择的实操建议4.1 安装方式conda还是pipPyTorch的安装主要有两种途径conda和pip。conda的优势是能管理CUDA工具链和系统依赖适合需要特定CUDA版本配合的场景pip的优势是轻量、和虚拟环境配合好适合纯Python项目。我的建议是如果你用Anaconda管理环境优先用conda安装因为conda会自动处理CUDA运行时库的匹配如果你用venv或poetry就用pip但要注意手动安装对应CUDA版本的wheel。安装命令在PyTorch官网有生成器选择你的操作系统、包管理器、CUDA版本后会给出具体命令。这里要强调一个常见坑不要盲目复制网上的安装命令一定要去官网确认当前稳定版和CUDA版本的对应关系。比如你的显卡驱动支持CUDA 12.1但你想装的PyTorch版本只提供CUDA 11.8的wheel那就需要降级或升级驱动否则运行时会报错。4.2 验证安装是否成功安装完成后用下面这段代码验证import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.device_count()) print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else No CUDA)如果torch.cuda.is_available()返回False常见原因有几个驱动版本太旧、CUDA运行时版本不匹配、或者安装的是CPU-only版本。排查顺序是先确认驱动支持的最高CUDA版本用nvidia-smi查看再确认安装的PyTorch编译时用的CUDA版本用torch.version.cuda查看两者需要兼容。4.3 虚拟环境与依赖管理强烈建议每个项目用独立的虚拟环境。PyTorch的版本迭代较快不同项目可能依赖不同版本混在一起容易出问题。用conda的话conda create -n myproject python3.10 conda activate myproject conda install pytorch torchvision torchaudio pytorch-cuda12.1 -c pytorch -c nvidia用venv的话python -m venv venv source venv/bin/activate # Linux/Mac # venv\Scripts\activate # Windows pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121把依赖导出成requirements.txt或environment.yml方便复现。我习惯在项目根目录放一个requirements.txt记录精确版本号比如torch2.1.0而不是torch2.0避免以后重装时版本漂移导致行为不一致。5. 训练流程的组织与关键环节5.1 数据管道Dataset与DataLoaderPyTorch的数据加载抽象很清晰Dataset负责定义单个样本的获取方式DataLoader负责批处理、打乱、多进程加载。自定义Dataset需要实现__len__和__getitem__from torch.utils.data import Dataset, DataLoader class MyDataset(Dataset): def __init__(self, data, labels, transformNone): self.data data self.labels labels self.transform transform def __len__(self): return len(self.data) def __getitem__(self, idx): x self.data[idx] y self.labels[idx] if self.transform: x self.transform(x) return x, y dataset MyDataset(data, labels) loader DataLoader(dataset, batch_size32, shuffleTrue, num_workers4, pin_memoryTrue)num_workers设置成CPU核心数的一半到全部之间比较合适太多会增加进程调度开销。pin_memoryTrue在GPU训练时能加速数据传输。如果数据加载成为瓶颈可以考虑把预处理结果缓存到磁盘或者用IterableDataset流式读取。5.2 模型定义nn.Module的组织方式定义模型的标准方式是继承nn.Module在__init__里声明层在forward里定义计算逻辑import torch.nn as nn class Net(nn.Module): def __init__(self, input_dim, hidden_dim, output_dim): super().__init__() self.fc1 nn.Linear(input_dim, hidden_dim) self.relu nn.ReLU() self.fc2 nn.Linear(hidden_dim, output_dim) def forward(self, x): x self.fc1(x) x self.relu(x) x self.fc2(x) return x几个实操要点层声明放在__init__里不要放在forward里否则每次前向都会重新创建层参数无法复用forward里可以用任意Python控制流如果有多层重复结构用nn.ModuleList或nn.Sequential组织不要用普通Python列表否则参数不会被注册。5.3 训练循环标准骨架与常见变体一个标准的训练循环包含前向传播、损失计算、反向传播、参数更新四步model Net(784, 256, 10).cuda() criterion nn.CrossEntropyLoss() optimizer torch.optim.Adam(model.parameters(), lr1e-3) for epoch in range(num_epochs): model.train() for batch_x, batch_y in train_loader: batch_x, batch_y batch_x.cuda(), batch_y.cuda() optimizer.zero_grad() outputs model(batch_x) loss criterion(outputs, batch_y) loss.backward() optimizer.step() model.eval() with torch.no_grad(): for batch_x, batch_y in val_loader: batch_x, batch_y batch_x.cuda(), batch_y.cuda() outputs model(batch_x) # 计算验证指标这里有几个容易忽略的细节model.train()和model.eval()会切换Dropout和BatchNorm的行为训练和验证阶段必须正确设置验证阶段用torch.no_grad()关闭梯度计算节省显存和计算optimizer.zero_grad()的位置可以在前向之前或之后但必须在backward()之前我习惯放在最前面逻辑更清晰。5.4 学习率调度与早停学习率是最重要的超参数之一。PyTorch提供了多种调度器scheduler torch.optim.lr_scheduler.StepLR(optimizer, step_size10, gamma0.1) # 或者 scheduler torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max50)调度器的step()调用时机要注意对于按epoch调整的调度器在每个epoch结束后调用对于按batch调整的在每个batch后调用。用错了会导致学习率变化不符合预期。早停是防止过拟合的常用手段。基本逻辑是监控验证集指标如果连续N个epoch没有提升就停止训练。实现上可以手动写一个计数器也可以用现成的工具库。我通常会在验证指标不再提升时保存最佳模型权重训练结束后加载最佳权重做最终评估。6. 常见问题与排查技巧实录6.1 显存不足OOM的排查思路显存不足是训练中最常见的问题之一。排查顺序如下排查项检查方法解决方向批次大小打印batch shape减小batch_size模型参数量统计可训练参数减小模型或冻结部分层中间激活用torch.cuda.memory_summary检查是否有不必要的中间变量梯度累积确认是否累积了多步梯度及时zero_grad数据加载确认pin_memory和num_workers调整或关闭一个容易被忽略的点是验证阶段如果没有用torch.no_grad()中间激活会保留计算图显存占用可能比训练还高。另外如果用了多个损失函数确保每个都正确释放。6.2 损失不下降或发散损失不下降的原因很多按可能性排序学习率太大或太小、数据没有正确归一化、标签和输出维度不匹配、损失函数选错、模型初始化有问题。我通常先做一个小实验用少量数据比如几十个样本过拟合如果模型能在这批数据上把损失降到接近零说明模型和训练流程基本正确问题出在数据或超参数上如果连过拟合都做不到那就是模型结构或代码有bug。学习率方面可以从1e-3开始试如果损失震荡就降到1e-4如果下降太慢就升到1e-2。用学习率扫描在几个数量级上各跑几百步能快速找到合适范围。6.3 训练和验证表现差距大训练集表现好但验证集差典型是过拟合。应对手段包括增加数据增强、加Dropout或权重衰减、减小模型容量、早停。但也要排除另一种可能验证集的数据预处理和训练集不一致。比如训练时做了归一化但验证时忘了或者训练用了数据增强但验证用了原始数据。这种“隐性bug”比过拟合更隐蔽建议在代码里把训练和验证的transform分开定义并打印几个样本确认。6.4 多卡训练的常见坑用DataParallel或DistributedDataParallel做多卡训练时常见问题包括模型没有正确移动到对应设备、损失没有做跨卡平均、BatchNorm的同步问题。DataParallel实现简单但效率一般DistributedDataParallel效率高但配置复杂。如果只是单机多卡DataParallel够用如果要多机多卡必须用DistributedDataParallel。一个实操建议先用单卡把流程跑通确认指标正常后再切多卡。多卡环境下很多bug会被掩盖比如批次大小变了导致学习率需要相应调整。7. 从实验到部署的过渡路径7.1 模型保存与加载PyTorch保存模型有两种方式保存整个模型torch.save(model, path)和只保存参数torch.save(model.state_dict(), path)。推荐后者因为保存整个模型会依赖具体的类定义迁移时容易出问题。加载时先实例化模型结构再加载参数model Net(784, 256, 10) model.load_state_dict(torch.load(model.pth)) model.eval()如果训练用了多卡保存的state_dict键名可能带module.前缀加载到单卡模型时需要去掉。可以用字典推导式处理state_dict torch.load(model.pth) new_state_dict {k.replace(module., ): v for k, v in state_dict.items()} model.load_state_dict(new_state_dict)7.2 推理优化量化与编译推理阶段可以考虑量化来减小模型体积和加速。PyTorch支持动态量化和静态量化# 动态量化 quantized_model torch.quantization.quantize_dynamic( model, {nn.Linear}, dtypetorch.qint8 )动态量化对LSTM和Linear层效果明显静态量化需要校准数据但精度更高。torch.compile是另一个优化手段在PyTorch 2.0之后可用compiled_model torch.compile(model)编译后的模型在首次运行时会有编译开销之后推理速度通常有提升。建议在部署前用真实数据做基准测试确认优化带来的收益值得增加的复杂度。7.3 导出为ONNX或其他格式如果需要跨框架部署可以导出为ONNXdummy_input torch.randn(1, 784).cuda() torch.onnx.export(model, dummy_input, model.onnx, input_names[input], output_names[output], dynamic_axes{input: {0: batch_size}})导出时要注意动态轴的定义否则模型只能接受固定批次大小。导出后用ONNX Runtime验证输出是否和PyTorch一致数值误差在1e-5以内算正常。8. 一些个人体会与后续扩展方向PyTorch用久了会发现它的学习曲线前期平缓、后期陡峭。入门很容易几行代码就能跑一个线性回归但要真正用好需要理解自动求导的边界、内存管理的细节、分布式训练的通信模式。我的建议是不要一开始就追求“最佳实践”先把一个完整项目跑通遇到问题再针对性深入。很多优化技巧在项目规模小的时候收益不明显过早引入反而增加心智负担。后续如果想继续深入几个方向值得投入一是自定义算子用C扩展或Triton写高性能kernel二是分布式训练理解DDP的通信机制和梯度同步策略三是模型压缩包括剪枝、量化、知识蒸馏的组合使用四是和推理引擎的配合比如TensorRT的集成。这些方向每一个都能展开成独立的话题但前提是基础训练流程已经足够熟练。最后分享一个小技巧在调试复杂模型时用torch.autograd.set_detect_anomaly(True)可以定位到产生NaN梯度的具体操作虽然会拖慢速度但在排查数值问题时非常有用。平时训练则关掉它避免不必要的开销。

相关新闻

从模糊需求到实时事件分析系统:基于rea的从零拆解与落地实践

从模糊需求到实时事件分析系统:基于rea的从零拆解与落地实践

1. 从“rea”这个标题说起:一个被低估的缩写背后藏着什么第一次看到“rea”这个标题的时候,我盯着屏幕愣了几秒。没有正文,没有关键词,没有摘要描述,就孤零零三个字母。这种极简到近乎“空白”的输入,反而让…

2026/10/15 5:43:36 阅读更多 →
Vivado HLS开发必读:UG871中文版核心实践指南

Vivado HLS开发必读:UG871中文版核心实践指南

简介:本资源是Xilinx官方《Vivado HLS教程》UG871中文版(v2020.1)完整PDF文档,面向FPGA开发初学者及Zynq平台工程师,聚焦高层次综合(HLS)技术入门与实践,解决传统Verilog/VHDL开发周…

2026/10/15 5:43:36 阅读更多 →
Edge WebGL警告:软件渲染自动回退已弃用,如何解决?

Edge WebGL警告:软件渲染自动回退已弃用,如何解决?

最近排查WebGL渲染问题的时候,好几个开发者都不约而同贴出了Edge控制台里的这段警告:Automatic fallback to software WebGL has been deprecated.初次看到的人多半会懵,以为自己写的三维渲染代码触发了什么严重错误,或者是显卡驱…

2026/10/15 5:43:36 阅读更多 →

最新新闻

使用 Hyper-V Integration Services WMI API 向虚拟机复制文件:Windows-classic-samples 实战解析

使用 Hyper-V Integration Services WMI API 向虚拟机复制文件:Windows-classic-samples 实战解析

示例工程 【免费下载链接】Windows-classic-samples This repo contains samples that demonstrate the API used in Windows classic desktop applications. 项目地址: https://gitcode.com/gh_mirrors/wi/Windows-classic-samples 点击查看 免费下载 导读 本文以…

2026/10/15 6:24:44 阅读更多 →
Pytest 测试框架实战:从 fixture 到参数化,打造优雅自动化测试工程

Pytest 测试框架实战:从 fixture 到参数化,打造优雅自动化测试工程

你有没有经历过这种时刻:写了好久业务代码,终于调通了,心里美滋滋,但转头一想到改完这模块可能把以前的功能搞坏,就又有点心虚。想写点测试吧,一看现有代码里那堆几十行重复的 setUp、tearDown,…

2026/10/15 6:24:44 阅读更多 →
考虑储能与新能源误差的售电公司购售电策略优化

考虑储能与新能源误差的售电公司购售电策略优化

1. 题目拆解:这个策略到底在解决售电公司的什么痛点拿到这个题目,先别急着看代码。我们需要把“考虑储能和可再生能源误差的售电公司购售电策略”这句话拆开,看清楚它到底在解决一个什么样的现实问题。售电公司这个角色,是电力市场…

2026/10/15 6:24:44 阅读更多 →
TCL脚本编程入门:解释器、字符串处理与实战避坑指南

TCL脚本编程入门:解释器、字符串处理与实战避坑指南

简介:这份中文版TCL教程PDF,定位为脚本语言入门与进阶的中文参考手册,面向自动化运维、嵌入式开发及需要编写脚本工具的技术人员。内容覆盖TCL核心语法、置换、变量、表达式、List、控制流、过程、字符串操作、文件访问、错误与异常&#xff…

2026/10/15 6:24:44 阅读更多 →
从问卷原始数据到可读热力图:matplotlib与seaborn实战指南

从问卷原始数据到可读热力图:matplotlib与seaborn实战指南

1. 从问卷原始数据到可读热力图:为什么这一步值得单独拿出来讲问卷数据大概是所有数据里最"脏"的一类。你回收上来的是几百上千行、每行几十列的原始记录,选项是"非常满意/满意/一般/不满意"这种文本,还夹杂着跳答、多选…

2026/10/15 6:24:44 阅读更多 →
Skills不是技能列表,而是一套可验证的能力操作系统

Skills不是技能列表,而是一套可验证的能力操作系统

项目标题是“skills”,这个词本身极简,却承载着极重的现实分量——它不是某个具体工具、框架或平台的代号,而是一组可迁移、可验证、可叠加的实践能力集合。在当下信息过载、技术迭代加速、岗位边界持续消融的环境中,“skills”早…

2026/10/15 6:23:44 阅读更多 →

日新闻

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