news 2026/8/29 15:44:48

知识蒸馏从原理到实战:避开过度蒸馏陷阱的PyTorch实现指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
知识蒸馏从原理到实战:避开过度蒸馏陷阱的PyTorch实现指南

这两年,“蒸馏”这个词已经从学术论文里跑进了开发者的日常交流。打开技术社区,能看到“用大模型蒸馏一个小模型”“把一本书蒸馏成 skill 知识库”“蒸馏一个专属智能体”这类说法。给人的感觉是:蒸馏就是万能压缩器,把大模型的能力倒进小模型,参数少一个数量级,效果只掉一点点。事实真是这样吗?

这篇文章不打算站队吹捧,也不打算全盘否定,只把蒸馏这件事讲清楚:蒸馏模型是什么意思、知识蒸馏的原理是什么、为什么现在会被过度神话、以及“过度蒸馏”到底会付出什么代价。文章后面会给出一个可以直接跑通的 PyTorch 蒸馏训练示例,包含蒸馏损失实现、温度参数分析和训练循环,最后附一套评估方法与常见问题排查清单。

适合的读者有三类:想用蒸馏压缩模型的算法工程师;在做大模型应用、考虑把 LLM 能力迁移到小模型的开发者;以及只在文章里看过“蒸馏”、想知道它到底怎么工作的同学。

1. 核心能力速览

能力项说明
技术类型模型压缩 / 知识迁移
核心机制Teacher-Student 框架,用大模型(教师)的软输出监督小模型(学生)
典型收益参数规模下降、推理成本降低、部署门槛降低、可在边缘设备运行
主要风险学生容量不足、教师错误继承、递归蒸馏导致模型坍缩、分布偏移
适用场景大模型压缩、跨架构迁移、无标签数据利用、多模型融合
不适用场景无损压缩、能力凭空创造、完全替代微调、解决数据质量问题
实现门槛需要可访问的教师模型(前向推理或预计算 logits)
典型工具PyTorch、TensorFlow、Hugging Face Transformers 等
评估维度精度、泛化、校准度、鲁棒性、OOD 表现
合规要点使用第三方模型输出训练需确认服务条款与数据授权

这里先给结论:蒸馏是一个真实有效、但也经常被误用的技术。它解决的是“知识迁移”问题,不是“能力创造”问题。理解了这个边界,后面的代价分析才有意义。

2. 蒸馏模型是什么意思:不只是“用大模型输出训练小模型”

2.1 最初的蒸馏:Hinton 的 Teacher-Student 框架

知识蒸馏(Knowledge Distillation)由 Hinton、Oriol Vinyals 和 Jeff Dean 在 2015 年提出,论文标题是Distilling the Knowledge in a Neural Network。核心思路非常直观:训练一个参数量更大的“教师模型”,然后用它来指导一个参数量更小的“学生模型”学习。

关键点在于,教师不直接给学生“标准答案”,而是给学生“概率分布”。比如图像分类任务里,一张猫的图片,教师模型输出的可能是“猫 91%、狮子 6%、老虎 3%”。传统训练只告诉学生“这是猫”,蒸馏则把“猫和狮子在特征上更接近,和汽车离得很远”这种暗知识(dark knowledge)也传给了学生。

这就是蒸馏模型最朴素的定义:学生模型不仅学习真实标签,还学习教师模型对样本的软性判断,从而把大模型的泛化能力“搬”到小模型上。

2.2 LLM 时代的蒸馏变体

到了大模型时代,“蒸馏”这个词被迅速泛化,出现了多种含义不同的用法:

  • 输出蒸馏:用大模型的生成结果或 logits 作为训练信号,监督小模型。这是最接近原始蒸馏的做法。
  • 数据蒸馏:先让大模型在无标签或弱标签数据上生成伪标签,再用这些伪标签训练小模型。工业界很常见,也叫“合成数据训练”。
  • 特征蒸馏:不仅匹配输出,还匹配中间层的特征表示。适合跨架构迁移。
  • 智能体 / skill 蒸馏:把复杂智能体的工作流、工具调用方式、知识库处理逻辑,提炼成更简单的 skill 或知识库。这类用法在智能体生态里很热,也和“把一本书蒸馏成 skill 知识库”的说法有关。

需要特别说明的是:最后一种“蒸馏”已经偏向产品化表达,和 Hinton 的原始定义距离较远。它更像“流程提炼”或“知识整理”,并不一定有神经网络训练过程。看到这类说法时,先确认对方说的是工程流程,还是真正的模型训练。

3. 知识蒸馏的原理:软标签、温度与 KL 散度

3.1 硬标签与软标签

传统分类训练用的是硬标签(hard label),也就是 one-hot 向量。学生模型训练时,只知道自己应该把“猫”这一类输出成 1,其他类输出成 0。这种方式的问题在于:它没有告诉学生“猫和狮子更像,猫和汽车更不像”,类别之间的相似关系被丢弃了。

蒸馏使用软标签(soft label),即教师模型在温度缩放后输出的概率分布。软标签包含的信息量远大于硬标签,尤其当某个样本本身有歧义时,教师给出的低置信度分布恰恰是学生最需要学习的“暗知识”。

3.2 温度参数的作用

为了让软标签更有信息量,Hinton 引入了温度参数 T。学生和教师在计算 softmax 之前,先把 logits 除以 T:

q_i = exp(z_i / T) / sum_j exp(z_j / T)
  • T = 1 时,就是普通 softmax。
  • T 越大,输出分布越平滑,类别间的相对关系越明显。
  • T 太大,分布接近均匀分布,类别细节被抹掉。
  • T 太小,分布接近硬标签,暗知识丢失。

所以温度不是越大越好,它决定“教师愿意透露多少细节”。同一个教师,T=3 和 T=8 教出来的学生,行为差异可能非常大。

3.3 蒸馏损失函数

蒸馏的总损失一般写成两部分:

  • 软损失:学生经过温度缩放后的输出分布,与教师软标签的 KL 散度。计算后要乘以 T²,因为 logits 被缩放后梯度会变小,乘回去才能保持梯度量级。
  • 硬损失:学生输出与真实硬标签的交叉熵,保证学生不偏离真实数据分布。

总损失是两者的加权和,权重由 alpha 控制。完整的蒸馏损失实现见第 6 节。

4. 为什么“蒸馏被妖魔化”了

说“妖魔化”,其实包含两层:一层是被当成万能神药,另一层是被当成简单复制、毫无技术含量。这两种极端都不对,但前者更危险,因为它会导致错误的工程决策。

被神化的典型说法包括:

  • “蒸馏可以无损压缩模型”:实际上蒸馏几乎总是有损的。学生模型容量更小,能容纳的信息上限天然更低。能在精度上逼近教师已经很好,说“无损”基本都是营销话术。
  • “蒸馏可以凭空创造能力”:学生只能学到教师已经具备的知识。如果教师本身不会某项技能,蒸馏一万次也造不出来。
  • “蒸馏次数越多越好”:对同一个学生反复蒸馏,边际收益递减,还有可能把教师的系统性错误越放越大。
  • “蒸馏可以替代微调”:蒸馏是知识迁移手段,目标场景是压缩和部署。如果任务本身数据质量差,蒸馏不会帮你变出好数据。
  • “用大模型输出训练小模型就是蒸馏”:这只是蒸馏的一种实现路径。真正做蒸馏,需要关注温度、损失权重、数据分布、容量匹配等一系列细节,远不是“调 API 跑一批数据再训练”这么简单。

被贬低的一面也存在:有人觉得蒸馏无非是“拿大模型的答案教小模型”,没有新东西。但实际做一次完整蒸馏就会发现,温度怎么选、alpha 怎么调、教师错误会不会被放大、学生容量够不够,每一项都可能决定项目成败。

5. 过度蒸馏的代价:五个具体风险

5.1 学生容量不够,知识装不下

这是最容易被忽略的问题。教师可能是 70B 参数的模型,学生只有 500M 参数。蒸馏的底层假设是“教师知识中存在冗余,小模型可以保留关键部分”,但冗余有限。当学生容量和教师知识量差距过大时,学生学到的是“近似中的近似”,精度会明显下降,而且不是靠调损失权重能救回来的。

更稳妥的方式是:先选定学生架构,做一次小规模蒸馏实验,观察学生相对教师的能力保留比例。如果保留比例过低,要么增大学生容量,要么先做数据筛选,只蒸馏目标任务最相关的子集。

5.2 教师的错误会被完整继承

蒸馏的本质是“模仿”。学生不只会学到教师正确的判断,还会学到教师系统性的错误和偏见。如果教师在某个类别上存在偏差,学生不仅学不到真实规律,还会把这个偏差固化。

这在医疗、金融、法律等高风险场景尤其危险。教师模型在训练数据上形成的偏见,会通过软标签完整传递给学生,而且学生容量更小、没有足够能力修正。实践中,蒸馏前必须评估教师模型在目标分布上的错误模式,必要时用干净数据对教师输出做校正。

5.3 软标签过软,类别边界被抹平

温度太高是过度蒸馏最常见的表现。当 T 取 8、10 甚至更高时,教师输出的分布趋于均匀,类别间差异被大幅削弱。学生接收到的信号变成“所有类别都差不多”,这会导致学生收敛变慢,甚至在几个相似类别之间反复摇摆。

另外,alpha 设置过大也不一定安全。软损失权重太高,学生过度拟合教师的输出分布,忽略真实标签,最后在训练集上表现不错,一到真实数据就掉链子。直接的经验是:温度先试 3~5,alpha 先试 0.6~0.8,再做网格搜索;不要一上来就用极端参数。

5.4 递归蒸馏与模型坍缩

“过度蒸馏”不单指单次蒸馏参数过头,还包括“反复对蒸馏产物再蒸馏”。当学生模型 A 蒸馏出 B,B 再蒸馏出 C,每一轮都会丢失一部分分布多样性。这个现象在生成模型领域已经被反复验证:模型在自身或同类模型生成的合成数据上反复训练,会导致输出多样性下降、错误累积,甚至出现“模型坍缩”(model collapse)。

这里说的是两件事:

  • 递归蒸馏:每一轮都把上一轮学生的输出当软标签。误差逐轮累积,最终学生可能只学到教师的一部分高频模式,低频但重要的模式被彻底丢掉。
  • 合成数据灌入:把大模型生成的文本、图像或标签数据反复加入训练集,但不去人工抽检。一开始可能提升数据量,多次迭代后,数据分布向内收缩,多样性下降。

应对方式:记录每一轮蒸馏后学生在独立评估集上的表现,如果出现连续两轮精度下滑或输出多样性下降,就应该停止递归蒸馏,回到真实数据上补充训练。

5.5 分布偏移与泛化下降

教师模型的训练数据和学生的部署数据往往存在差异。教师可能是用通用数据训练的,而学生要部署到特定业务场景。蒸馏最理想的情况是:教师和学生在同一分布上训练,学生把教师在分布内的知识学走。但如果部署场景分布发生了变化,学生学到的其实是“教师对旧分布的理解”,对真实新分布的适应能力反而不如直接用新数据微调的小模型。

更麻烦的是,很多过度蒸馏流程会让学生只见过教师“觉得重要”的样本,真实数据中大量长尾样本被过滤掉了。这会让学生的泛化能力比预期差很多。

6. 蒸馏实战:从损失函数到训练循环

6.1 蒸馏损失实现

下面是一个完整的 PyTorch 蒸馏损失实现,可以直接嵌入训练脚本。

import torch import torch.nn as nn import torch.nn.functional as F def distillation_loss( student_logits: torch.Tensor, teacher_logits: torch.Tensor, labels: torch.Tensor, temperature: float = 4.0, alpha: float = 0.7, ) -> torch.Tensor: """ 蒸馏损失 = alpha * KL(学生软输出, 教师软输出) + (1 - alpha) * CE(学生输出, 硬标签) 参数: student_logits: 学生模型原始 logits, shape (B, C) teacher_logits: 教师模型原始 logits, shape (B, C) labels: 真实标签, shape (B,) temperature: 温度 T alpha: 软损失权重 """ # 软损失: 两者都除以 T soft_loss = nn.KLDivLoss(reduction="batchmean")( F.log_softmax(student_logits / temperature, dim=-1), F.softmax(teacher_logits / temperature, dim=-1), ) # logits 被缩放后梯度变小, 乘回 T^2 保持梯度量级 soft_loss = soft_loss * (temperature * temperature) # 硬损失: 学生输出 vs 真实硬标签 hard_loss = F.cross_entropy(student_logits, labels) return alpha * soft_loss + (1.0 - alpha) * hard_loss

6.2 温度对软标签的影响

先用一个小实验理解温度。给出一组手工构造的 logits[2.0, 1.0, 0.1, 0.05, 0.01],观察不同温度下的 softmax 分布:

import torch import torch.nn.functional as F logits = torch.tensor([2.0, 1.0, 0.1, 0.05, 0.01]) for T in [1.0, 2.0, 4.0, 8.0, 16.0]: probs = F.softmax(logits / T, dim=-1) print(f"T={T:>5.1f} -> {probs.numpy().round(4)}")

输出趋势:

T= 1.0 -> [0.586 0.215 0.087 0.083 0.080] T= 2.0 -> [0.370 0.223 0.146 0.141 0.138] T= 4.0 -> [0.257 0.191 0.151 0.148 0.147] T= 8.0 -> [0.214 0.182 0.158 0.156 0.156] T=16.0 -> [0.195 0.176 0.165 0.164 0.164]

可以看到,T=1 时模型几乎只关注最大类别;T 越大,分布越平。温度太高时,分布接近均匀,学生学习不到类别间的精细差异。所以蒸馏时温度选择一个中间值(通常 3~6)比较合适,具体值要做实验。

6.3 学生模型训练循环

下面是一个完整的训练循环,兼容 GPU 和 CPU。注意教师模型必须设置为eval()模式并用torch.no_grad()包裹,避免反向传播到教师。

import torch from torch.utils.data import DataLoader def evaluate(model, val_loader, device): model.eval() correct, total = 0, 0 with torch.no_grad(): for x, y in val_loader: x, y = x.to(device), y.to(device) pred = model(x).argmax(dim=-1) correct += (pred == y).sum().item() total += y.size(0) return correct / total def train_student( student, teacher, train_loader: DataLoader, val_loader: DataLoader, device, temperature: float = 4.0, alpha: float = 0.7, epochs: int = 20, lr: float = 1e-4, ): optimizer = torch.optim.AdamW(student.parameters(), lr=lr) teacher = teacher.to(device) student = student.to(device) for epoch in range(epochs): student.train() teacher.eval() total_loss = 0.0 for x, labels in train_loader: x, labels = x.to(device), labels.to(device) with torch.no_grad(): teacher_logits = teacher(x) student_logits = student(x) loss = distillation_loss( student_logits, teacher_logits, labels, temperature=temperature, alpha=alpha, ) optimizer.zero_grad() loss.backward() optimizer.step() total_loss += loss.item() val_acc = evaluate(student, val_loader, device) print(f"epoch {epoch + 1:3d}/{epochs} | " f"loss {total_loss / len(train_loader):.4f} | " f"val_acc {val_acc:.4f}")

这段代码的关键点有三个:

  • 教师始终在no_grad下推理,避免额外显存开销。
  • 软损失乘回T * T,否则梯度量级会随温度变大而变小。
  • 硬损失始终保留,防止学生完全偏离真实标签。

6.4 训练配置模板

实际跑实验时,建议把超参集中到一个 JSON 配置文件里,方便做多组对比:

{ "teacher": "resnet50_teacher.pth", "student_arch": "resnet18", "data_dir": "./data/classification", "output_dir": "./runs/distill_exp01", "temperature": 4.0, "alpha": 0.7, "epochs": 20, "batch_size": 128, "lr": 0.0001, "log_interval": 50, "seed": 42 }

用配置文件而不是硬编码参数,能显著减少对比实验的混乱程度。每次改动只改 JSON 里的一个字段,跑完自动存一份副本,后面复盘时可以直接定位是哪组参数导致的效果变化。

7. 如何评估一次蒸馏是否成功

7.1 精度不是唯一指标

很多团队只看学生模型在验证集上的精度,这不够。蒸馏是“模拟教师”,所以评估时至少要同时看四个维度:

  • 精度:学生相对教师的能力保留比例,即学生精度 / 教师精度
  • 分布对齐度:学生输出分布与教师输出分布的相似程度,例如两者在测试集上的平均 KL 散度。
  • 校准度:学生的置信度是否和真实正确率一致。过度蒸馏经常让学生变得“过度自信”或“过度保守”。
  • OOD 表现:学生模型在分布外样本上的表现。如果蒸馏只让学生记住了教师的判断模式,OOD 表现可能会很差。

7.2 对比实验设计

建议至少跑四组:

  1. 学生直接使用硬标签训练,不蒸馏(基线)。
  2. 学生蒸馏训练,温度固定,alpha 变化。
  3. 学生蒸馏训练,alpha 固定,温度变化。
  4. 在第二或第三组最佳配置基础上,做蒸馏后微调(先用蒸馏损失,再用小学习率、普通交叉熵微调几个 epoch)。

只有同时拿到这四组数据,才能判断“效果提升来自蒸馏,还是来自训练参数本身”。

7.3 判断失败的信号

  • 学生精度比基线还低,先检查温度是否过高、alpha 是否过大。
  • 训练 loss 下降但验证精度长期不动,优先怀疑学生容量不足,而不是继续调超参。
  • 学生在训练类目上表现好,但真实业务数据表现差,说明蒸馏数据分布和部署分布不一致。
  • 学生输出和教师输出高度一致,但两者在真实数据上都错,说明问题出在教师而不是蒸馏流程。

8. 蒸馏、量化与剪枝:压缩方案怎么选

蒸馏是“知识迁移”,量化是“数值精度压缩”,剪枝是“结构稀疏化”。三者解决不同问题,也可以组合使用,但不应该被混淆。

方案原理典型收益主要风险适用场景
知识蒸馏小模型学习大模型的软输出参数减少、能力迁移教师错误继承、容量不匹配从大模型到小模型的跨架构迁移
量化用低精度数值表示权重和激活模型体积下降、推理加速精度损失、算子兼容已有模型直接部署,不换架构
剪枝去掉不重要的参数、通道或层模型体积下降、推理加速结构依赖、需要微调恢复模型有大量冗余参数时

选择顺序建议是:先明确部署硬件和延迟要求;再评估现有模型是否可以直接量化;如果量化后精度损失过大,再考虑蒸馏一个更小的学生模型;学生模型还可以继续量化,形成“蒸馏 + 量化”的组合方案。注意,蒸馏和量化叠加时,每一步都会引入损耗,最终效果要以端到端评估为准。

9. 常见问题与排查方法

问题现象可能原因排查方式解决方案
学生精度比直接训练还低温度过高、alpha 过大、学生容量不足先用 T=1、alpha=0 跑基线降低温度到 3~5,降低 alpha 到 0.5~0.7;增大学生模型
训练 loss 下降但验证精度不动软标签分布过于平滑,学生没有学到判别信息打印教师软标签的熵值降低温度;检查教师模型是否已经退化
蒸馏后在真实业务数据表现差蒸馏数据分布与部署分布不一致对比蒸馏数据与业务数据的特征分布在业务分布上补充伪标签数据,或引入真实样本微调
学生模型输出和教师几乎一样alpha 过高,学生完全拟合教师检查软损失占比降低 alpha,保留更多硬标签信号
递归蒸馏几轮后输出多样性下降误差累积或模型坍缩记录每轮学生输出分布的熵停止递归,回到真实数据训练;加入多样性约束
训练显存不足教师模型前向推理占用显存查看教师和学生的显存占用提前预计算教师 logits 存到磁盘;减小 batch size
蒸馏训练时间过长每步都要教师前向推理统计教师前向耗时离线缓存教师输出,训练时直接读取
教师模型有系统性错误教师本身在部分类别上偏差大分类别评估教师精度校正教师输出,或对错误类别的样本降权

10. 最佳实践与合规边界

10.1 工程实践建议

  • 先跑基线,再谈蒸馏。学生直接硬标签训练的精度是底线,蒸馏后的效果要超过这个底线才有意义。
  • 离线缓存教师输出。教师模型通常很大,训练中反复前向推理成本高。建议先一次性跑完所有训练样本的教师 logits,存成.npy.pt文件,训练时直接加载。
  • 做超参小网格。温度建议在[2, 3, 4, 5, 6]里选,alpha 在[0.4, 0.6, 0.7, 0.8]里选。不需要全组合,先固定 alpha 找温度,再固定温度找 alpha。
  • 监控教师错误率。如果教师本身在某个子集上错误率很高,直接蒸馏会把错误放大。可以针对这些子集降低损失权重。
  • 蒸馏后做短微调。用蒸馏损失训练完,再用小学习率、纯硬标签损失做几个 epoch 的微调,通常能修正过度平滑的问题。
  • 保留最小可运行配置。把数据路径、模型路径、蒸馏配置都参数化,出一个配置文件示例,后续复制改字段即可。

10.2 数据与授权合规

蒸馏涉及两个层面的合规问题,容易被忽略:

  • 模型服务条款。如果教师模型来自第三方 API,用 API 输出训练自己的模型前,必须先确认服务条款中关于输出数据再训练的规定。部分服务明确禁止此类用途。
  • 数据授权。如果蒸馏数据来自版权书籍、专利文档、付费内容或用户隐私,需要确认使用范围和授权边界。尤其“把一本书蒸馏成知识库”这类场景,涉及版权内容的提取和再组织,必须确认是否可以合法使用、是否可以商用。

此外,涉及人脸、声音、医疗、金融等敏感数据时,蒸馏同样不豁免隐私保护义务。建议在蒸馏流程中加入数据脱敏、访问控制和输出审计,生产环境部署前做安全性和公平性评估。

11. 总结与下一步

蒸馏是一个成熟且有效的技术,前提是:学生容量匹配、教师质量可靠、温度与权重合理、数据分布与部署一致。当这些前提不成立时,蒸馏就会从“能力迁移”变成“错误复制”,过度迭代还会引发模型坍缩和泛化下降。

如果你正准备在自己的项目里用蒸馏,建议按这个顺序行动:

  1. 先用一个你能完全掌控的教师,跑通第 6 节的训练示例。
  2. 记录学生相对教师的能力保留比例。
  3. 做一组“蒸馏 vs 纯硬标签”的对比实验,用数据决定要不要继续。
  4. 如果决定蒸馏,把教师输出缓存下来,省训练时间。
  5. 上线前检查数据授权、模型服务条款和输出质量。

蒸馏最值得尝试的点,是它能在不大幅损失能力的情况下,把模型的部署成本降下来。最先要验证的,永远不是“蒸馏能到多少分”,而是“在你的数据和架构下,蒸馏是否真的比直接训练更好”。

最容易踩的坑有三个:温度拉太高、学生容量和教师差距过大、用蒸馏掩盖数据质量问题。避开这三个坑,蒸馏大概率能给你带来实际收益。

之后再扩展的方向也很明确:尝试特征蒸馏、结合量化压缩、在 LLM 场景做数据蒸馏并用独立评估集监控分布退化。每一步都能继续展开,但前提都是先把手里的蒸馏基线做扎实。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/29 15:44:20

基于SpringBoot的校园资讯交流平台系统(源码+lw+部署文档+讲解等)

联系博主 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 …

作者头像 李华
网站建设 2026/8/29 15:42:02

网易校招机器学习算法笔试题全解析:从KMP到模型评估与特征工程

网易2018校招机器学习算法工程师笔试卷,现在回过头看依然是一份很有代表性的考察样本。那阵子算法岗远没有现在这么卷,但这张卷子已经相当扎实地覆盖了机器学习与算法的核心骨架:数据结构、经典算法、统计学习理论、模型评估、特征工程&#…

作者头像 李华
网站建设 2026/8/29 15:40:44

PaddleOCR:如何让设备铭牌数据入库快3倍

PaddleOCR:如何让设备铭牌数据入库快3倍 【免费下载链接】PaddleOCR Turn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between images/PDFs and LLMs. Supports 100 languages. 项目…

作者头像 李华
网站建设 2026/8/29 15:38:11

Scrapling 快速上手教程:让爬虫脚本扛住网站改版

Scrapling 快速上手教程:让爬虫脚本扛住网站改版 【免费下载链接】Scrapling 🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! 项目地址: https://gitcode.com/GitHub_Trending/sc/Sc…

作者头像 李华
网站建设 2026/8/29 15:37:54

如何用codex resume继续任务:codex-plugin-cc到Codex App的完整交接

如何用codex resume继续任务:codex-plugin-cc到Codex App的完整交接 【免费下载链接】codex-plugin-cc Use Codex from Claude Code to review code or delegate tasks. 项目地址: https://gitcode.com/GitHub_Trending/co/codex-plugin-cc codex-plugin-cc …

作者头像 李华