在目标检测模型的部署实践中我们常常面临一个两难选择追求极致精度的大模型还是追求实时速度的小模型大模型如 YOLOv8x 虽然精度高但计算开销大难以在资源受限的边缘设备上流畅运行而小模型如 YOLOv8n 虽然速度快但精度往往不尽如人意可能无法满足业务对准确性的要求。有没有一种方法能让小模型“继承”大模型的“智慧”在不增加推理成本的前提下显著提升其精度呢答案是肯定的这就是知识蒸馏技术。本文将围绕“知识蒸馏”这一核心手把手带你完成一个完整的实战项目让 YOLOv8x 这位“私教”来训练 YOLOv8n 这位“学生”目标是将 YOLOv8n 在 COCO 数据集上的 mAP 指标从约 37% 提升到 42% 以上。我们将从原理、环境搭建、代码实现到结果分析为你呈现一个清晰、可复现的完整流程。无论你是刚接触模型优化的新手还是希望将知识蒸馏应用于实际项目的开发者都能从本文中获得实用的指导和代码。1. 背景与核心概念为什么需要知识蒸馏在深入代码之前我们有必要理解知识蒸馏要解决的根本问题以及其背后的核心思想。1.1 模型部署的“精度-速度”权衡在计算机视觉领域特别是目标检测任务中模型的性能通常由两个关键维度衡量精度 (Accuracy)模型预测的准确程度常用 mAP (mean Average Precision平均精度均值) 等指标评估。速度/效率 (Speed/Efficiency)模型进行单次预测所需的时间或计算资源常用 FPS (Frames Per Second) 或 FLOPs (Floating Point Operations) 衡量。通常模型越大、参数越多如 YOLOv8x其学习能力越强精度越高但推理速度越慢对硬件要求也越高。反之模型越小如 YOLOv8n速度越快但精度会有所牺牲。这种矛盾在移动端、嵌入式设备或需要高吞吐量的在线服务中尤为突出。1.2 知识蒸馏一种高效的模型压缩与迁移技术知识蒸馏是一种模型压缩技术其灵感来源于教育中的“教师-学生”模式。其核心思想是将一个已经训练好的、性能强大的复杂模型教师模型所学习到的“知识”迁移到一个结构更简单、参数更少的模型学生模型中去。这里的“知识”并不仅仅是教师模型最终的硬标签输出如“这是一只猫”更重要的是其输出的概率分布软标签即模型对于各个类别的“置信度”。例如一张模糊的图片教师模型可能输出[猫: 0.7, 狗: 0.25, 狐狸: 0.05]。这个概率分布包含了比硬标签[猫: 1, 狗: 0, 狐狸: 0]更丰富的信息比如类别间的相似性关系猫和狗在某些特征上可能更接近。学生模型通过学习这种更“软”、更“平滑”的标签能够获得更好的泛化能力。1.3 知识蒸馏在 YOLO 系列中的应用价值YOLOv8 提供了从 nano (n) 到 extra-large (x) 的一系列预训练模型。YOLOv8x 作为最大的模型在 COCO 数据集上可以达到很高的 mAP例如 53.9%而 YOLOv8n 的 mAP 则在 37% 左右。直接使用 YOLOv8n 可能无法满足精度要求而部署 YOLOv8x 又面临资源压力。通过知识蒸馏我们可以免费提升小模型性能在不改变 YOLOv8n 网络结构即不增加推理时计算量的前提下利用 YOLOv8x 的知识来提升其精度。定制化优化可以在特定领域的数据集上用该领域的大模型教师来蒸馏小模型学生使其在该领域表现更佳。突破小模型的理论上限学生模型有可能学到教师模型的一些“推理技巧”从而超越其单独训练所能达到的性能天花板。本文的目标就是验证并实现这一过程将 YOLOv8n 的精度从基线 37% 提升到 42%。2. 环境准备与版本说明为了确保实验的可复现性以下是本次实战所使用的核心环境与工具。你的环境可以略有不同但主要库的大版本建议保持一致。2.1 硬件与操作系统操作系统Ubuntu 20.04 LTS 或 Windows 10/11 (WSL2 推荐)CPU8 核以上GPUNVIDIA GPU (显存 8GB如 RTX 3070/4070 或更高)用于加速训练。CPU 亦可但训练速度极慢。内存16GB 以上2.2 软件与库版本以下是经过测试的稳定版本组合# 核心深度学习框架 Python 3.8.10 PyTorch 1.12.1cu113 # 请根据你的CUDA版本选择CUDA 11.3是一个常见选择 torchvision 0.13.1cu113 # YOLOv8 官方库 ultralytics 8.0.196 # 确保版本 8.0.145其中包含了蒸馏训练的支持 # 其他工具库 numpy 1.23.5 opencv-python 4.8.1.78 matplotlib 3.7.1 seaborn 0.12.2 tqdm 4.65.0 pycocotools 2.0.6 # 用于COCO指标评估2.3 环境搭建步骤创建并激活 Conda 环境推荐conda create -n yolov8_distill python3.8 -y conda activate yolov8_distill安装 PyTorch 访问 PyTorch 官网 根据你的 CUDA 版本获取安装命令。例如对于 CUDA 11.3pip install torch1.12.1cu113 torchvision0.13.1cu113 --extra-index-url https://download.pytorch.org/whl/cu113安装 Ultralytics YOLOv8pip install ultralytics8.0.196验证安装import torch from ultralytics import YOLO print(torch.__version__) print(torch.cuda.is_available()) # 应返回 True model YOLO(yolov8n.pt) # 这会自动下载预训练权重 print(model.info()) # 打印模型信息2.4 数据集准备我们将使用COCO 2017数据集的一个子集进行演示以控制训练时间和资源消耗。你可以使用完整数据集以获得更通用的效果。训练集coco/train2017(约 118K 张图片)验证集coco/val2017(约 5K 张图片)注释文件coco/annotations/instances_train2017.json,instances_val2017.json目录结构建议your_project/ ├── data/ │ └── coco/ │ ├── train2017/ # 训练图片 │ ├── val2017/ # 验证图片 │ └── annotations/ │ ├── instances_train2017.json │ └── instances_val2017.json ├── models/ # 存放教师、学生模型权重 ├── runs/ # 训练日志和结果由YOLO自动生成 └── distill_train.py # 我们的蒸馏训练脚本你可以从 COCO 官网 下载数据集并使用上述结构组织。3. 知识蒸馏核心原理与 YOLOv8 实现拆解在动手写代码前我们需要理解 YOLOv8 是如何实现知识蒸馏的这有助于我们更好地配置参数和理解训练过程。3.1 蒸馏损失函数软目标与硬目标的结合YOLOv8 的蒸馏训练通常结合两种损失蒸馏损失 (Distillation Loss)衡量学生模型输出与教师模型“软标签”输出之间的差异。常用 KL 散度 (Kullback-Leibler Divergence) 或均方误差 (MSE)。软标签教师模型对每个预测框产生的类别概率分布经过温度参数 T 平滑。温度参数 T一个超参数。T1 时就是原始的 softmax 输出T1 时概率分布变得更“软”、更平滑蕴含更多类别间关系信息。学生损失 (Student Loss)即原始的目标检测损失衡量学生模型输出与真实标注硬标签之间的差异。包括边界框回归损失 (如 CIOU Loss)目标置信度损失 (如 BCE Loss)分类损失 (如 BCE Loss)总损失函数通常是两者的加权和总损失 α * 学生损失 β * 蒸馏损失其中 α 和 β 是超参数用于平衡从真实数据学习和从教师模型学习的比重。3.2 YOLOv8 蒸馏训练流程Ultralytics 框架已经将蒸馏流程封装得非常完善其内部流程可以概括为加载教师模型加载一个预训练好的、冻结权重的大模型如yolov8x.pt。加载学生模型初始化或加载一个小模型如yolov8n.pt。前向传播同一批训练数据分别输入教师模型和学生模型。损失计算计算学生模型的检测损失同时计算学生输出与教师输出之间的蒸馏损失。反向传播与优化只对学生模型的参数进行梯度计算和更新教师模型的参数保持不变。迭代重复步骤 3-5直到学生模型收敛。3.3 关键超参数解析在 YOLOv8 的蒸馏配置中以下几个参数至关重要teacher_model: 教师模型权重文件的路径。distill_loss: 蒸馏损失的类型如‘kl’(KL散度) 或‘mse’(均方误差)。distill_weight: 对应上述的 β蒸馏损失的权重。值越大学生模型越倾向于模仿教师。temperature: 软化标签的温度参数 T。teacher_input_size: 教师模型的输入图像尺寸。有时为了节省内存可以用比学生模型更大的尺寸输入教师模型以获取更丰富的特征。理解这些原理后我们就可以开始编写具体的训练代码了。4. 完整实战YOLOv8x 蒸馏训练 YOLOv8n接下来我们将分步骤实现整个蒸馏流程。请确保你的环境已按第 2 节配置好并且数据集已就位。4.1 步骤一准备教师与学生模型首先我们需要下载教师模型YOLOv8x和学生模型YOLOv8n的预训练权重。Ultralytics 的YOLO类在首次加载时会自动下载。# file: prepare_models.py from ultralytics import YOLO import torch def download_pretrained_models(): 下载教师和学生模型的预训练权重 print(正在下载 YOLOv8n (学生模型) 预训练权重...) student_model YOLO(yolov8n.pt) # 自动下载 yolov8n.pt print(f学生模型下载完成保存于: yolov8n.pt) print(正在下载 YOLOv8x (教师模型) 预训练权重...) teacher_model YOLO(yolov8x.pt) # 自动下载 yolov8x.pt print(f教师模型下载完成保存于: yolov8x.pt) # 简单验证模型加载 print(f学生模型结构: {student_model.model}) print(f教师模型结构: {teacher_model.model}) print(fCUDA 可用: {torch.cuda.is_available()}) if __name__ __main__: download_pretrained_models()运行此脚本模型权重会自动下载到当前目录。4.2 步骤二编写蒸馏训练配置文件YOLOv8 支持通过 YAML 文件配置训练参数。我们创建一个专门用于蒸馏的配置文件。# file: cfg/distill_coco.yaml # 蒸馏训练配置 # 基础训练参数 path: ./data/coco # 数据集的根目录 train: train2017 # 训练集图片目录相对于 path val: val2017 # 验证集图片目录相对于 path # 模型参数 model: yolov8n.pt # 学生模型初始权重 teacher_model: yolov8x.pt # 教师模型权重路径 imgsz: 640 # 学生模型的输入图像尺寸 teacher_imgsz: 640 # 教师模型的输入图像尺寸可以与学生不同 # 蒸馏特定参数 distill: true # 开启蒸馏训练 distill_loss: kl # 使用 KL 散度作为蒸馏损失 distill_weight: 0.5 # 蒸馏损失的权重 (beta)需要调试 temperature: 4.0 # 软化标签的温度参数 T # 优化器与调度器 lr0: 0.01 # 初始学习率 lrf: 0.01 # 最终学习率因子 (lr0 * lrf) momentum: 0.937 weight_decay: 0.0005 warmup_epochs: 3.0 warmup_momentum: 0.8 warmup_bias_lr: 0.1 # 训练超参数 epochs: 100 # 总训练轮数 batch: 16 # 批次大小根据GPU显存调整 workers: 8 # 数据加载线程数 device: 0 # 使用 GPU 0如果是 CPU 则设为 ‘cpu’ seed: 42 # 验证与保存 save: true save_period: -1 # 每 N 轮保存一次检查点-1 表示只在最后保存 cache: false # 是否缓存数据集True 可加速但耗内存 project: runs/distill # 结果保存目录 name: exp # 实验名称 exist_ok: true # 是否覆盖同名实验 # 数据增强 hsv_h: 0.015 # 色调增强 hsv_s: 0.7 # 饱和度增强 hsv_v: 0.4 # 明度增强 degrees: 0.0 # 旋转角度 translate: 0.1 # 平移 scale: 0.5 # 缩放 shear: 0.0 # 剪切 perspective: 0.0 # 透视变换 flipud: 0.0 # 上下翻转概率 fliplr: 0.5 # 左右翻转概率 mosaic: 1.0 # Mosaic 数据增强概率 mixup: 0.0 # MixUp 增强概率 copy_paste: 0.0 # 复制粘贴增强概率关键配置解释distill: true这是触发蒸馏训练的总开关。teacher_model必须指向一个有效的.pt权重文件。distill_weight本例设为 0.5意味着学生损失和蒸馏损失各占一半权重。这是一个需要根据任务调整的核心超参数。temperature设为 4.0是一个常用的起始值用于软化教师模型的输出分布。4.3 步骤三启动蒸馏训练现在我们可以使用 Ultralytics 的高级 API 来启动训练。创建一个 Python 脚本作为训练入口。# file: distill_train.py from ultralytics import YOLO import argparse import os def main(args): 主函数启动 YOLOv8 知识蒸馏训练 Args: args: 命令行参数 # 加载学生模型将进行训练 print(f加载学生模型: {args.student_model}) model YOLO(args.student_model) # 开始训练 # 关键通过 cfg 参数传递配置字典其中包含 teacher_model 等蒸馏设置 results model.train( dataargs.data_config, # 数据集配置文件路径 epochsargs.epochs, imgszargs.imgsz, batchargs.batch, deviceargs.device, workersargs.workers, projectargs.project, nameargs.name, exist_okTrue, # 以下是传递给训练器的额外参数用于控制蒸馏 teacher_modelargs.teacher_model, # 指定教师模型 distillargs.distill, # 开启蒸馏 distill_lossargs.distill_loss, # 蒸馏损失类型 distill_weightargs.distill_weight,# 蒸馏损失权重 temperatureargs.temperature, # 温度参数 teacher_imgszargs.teacher_imgsz, # 教师模型输入尺寸 # 优化器参数 lr0args.lr0, momentumargs.momentum, weight_decayargs.weight_decay, warmup_epochsargs.warmup_epochs, # 数据增强参数示例 hsv_h0.015, hsv_s0.7, hsv_v0.4, fliplr0.5, ) print(训练完成) # 打印关键指标 if results: print(f最佳 mAP50-95: {results.box.map:.4f}) print(f最佳 mAP50: {results.box.map50:.4f}) # 在验证集上评估最终模型 print(\n开始在验证集上评估最终模型...) metrics model.val( dataargs.data_config, imgszargs.imgsz, batchargs.batch * 2, # 评估时可以用更大的batch deviceargs.device, projectargs.project, namef{args.name}_val, ) print(f验证集 mAP50-95: {metrics.box.map:.4f}) print(f验证集 mAP50: {metrics.box.map50:.4f}) return model, results, metrics if __name__ __main__: parser argparse.ArgumentParser(descriptionYOLOv8 Knowledge Distillation Training) # 模型参数 parser.add_argument(--student_model, typestr, defaultyolov8n.pt, help学生模型权重路径) parser.add_argument(--teacher_model, typestr, defaultyolov8x.pt, help教师模型权重路径) parser.add_argument(--data_config, typestr, defaultcoco.yaml, help数据集配置文件路径) # 蒸馏参数 parser.add_argument(--distill, actionstore_true, defaultTrue, help是否启用蒸馏) parser.add_argument(--distill_loss, typestr, defaultkl, choices[kl, mse], help蒸馏损失类型) parser.add_argument(--distill_weight, typefloat, default0.5, help蒸馏损失权重) parser.add_argument(--temperature, typefloat, default4.0, help温度参数) parser.add_argument(--teacher_imgsz, typeint, default640, help教师模型输入尺寸) # 训练参数 parser.add_argument(--epochs, typeint, default100, help训练轮数) parser.add_argument(--imgsz, typeint, default640, help输入图像尺寸) parser.add_argument(--batch, typeint, default16, help批次大小) parser.add_argument(--device, typestr, default0, help设备如 0,1,2,3 或 cpu) parser.add_argument(--workers, typeint, default8, help数据加载线程数) parser.add_argument(--lr0, typefloat, default0.01, help初始学习率) parser.add_argument(--momentum, typefloat, default0.937, help动量) parser.add_argument(--weight_decay, typefloat, default0.0005, help权重衰减) parser.add_argument(--warmup_epochs, typefloat, default3.0, help热身轮数) # 日志与保存 parser.add_argument(--project, typestr, defaultruns/distill, help项目保存目录) parser.add_argument(--name, typestr, defaultexp, help实验名称) args parser.parse_args() # 确保教师模型文件存在 if not os.path.exists(args.teacher_model): raise FileNotFoundError(f教师模型权重文件未找到: {args.teacher_model}。请先运行 prepare_models.py 下载。) # 启动训练 model, results, metrics main(args)运行训练 在终端中执行以下命令开始蒸馏训练。请根据你的 GPU 显存调整--batch大小。python distill_train.py \ --student_model yolov8n.pt \ --teacher_model yolov8x.pt \ --data_config ./data/coco.yaml \ # 你需要一个指向你数据集的coco.yaml --epochs 50 \ # 为了演示可以先训练50轮 --batch 8 \ # 如果显存不足减小此值 --device 0 \ --distill_weight 0.5 \ --project runs/distill_coco \ --name yolov8n_distilled注意你需要准备一个coco.yaml文件其内容类似于# coco.yaml path: /path/to/your/data/coco # 数据集根目录 train: train2017 val: val2017 # 类别名 names: 0: person 1: bicycle # ... 其余 78 个类别 79: toothbrush4.4 步骤四监控训练过程与结果分析训练开始后Ultralytics 会在--project指定的目录下如runs/distill_coco/yolov8n_distilled生成一系列日志和结果文件。终端输出你会看到每个 epoch 的训练损失、验证指标mAP50, mAP50-95等。TensorBoard 日志在runs/目录下会生成事件文件可以使用 TensorBoard 可视化。tensorboard --logdir runs/distill_coco结果图片训练完成后在实验目录下会生成一系列图表如results.png损失和指标曲线、confusion_matrix.png等。关键指标观察train/box_loss,train/distill_loss分别代表学生检测损失和蒸馏损失。观察两者是否在平稳下降。metrics/mAP50(B)和metrics/mAP50-95(B)这是最重要的精度指标。mAP50是 IoU 阈值为 0.5 时的平均精度mAP50-95是 IoU 阈值从 0.5 到 0.95 的平均值即常说的 mAP。我们的目标就是提升mAP50-95。4.5 步骤五评估与对比训练结束后我们需要系统地评估蒸馏后的学生模型并与基线模型未蒸馏的 YOLOv8n进行对比。1. 评估蒸馏后的模型 使用训练脚本中内置的model.val()或在训练完成后单独运行评估# file: evaluate_model.py from ultralytics import YOLO # 加载训练得到的最佳模型权重 # 权重通常保存在 runs/distill_coco/yolov8n_distilled/weights/best.pt distilled_model YOLO(runs/distill_coco/yolov8n_distilled/weights/best.pt) # 在验证集上进行评估 metrics distilled_model.val( datacoco.yaml, imgsz640, batch32, device0, save_jsonTrue, # 保存 JSON 格式的评估结果 projectruns/eval, namedistilled_yolov8n ) print(f蒸馏后模型 mAP50-95: {metrics.box.map:.4f}) print(f蒸馏后模型 mAP50: {metrics.box.map50:.4f})2. 评估基线模型未蒸馏的 YOLOv8n 为了公平对比我们需要在完全相同的数据集和评估设置下评估原始的 YOLOv8n 预训练模型或者从头训练一个 YOLOv8n。# 评估原始预训练模型这代表了在 COCO 上预训练的性能 baseline_pretrained YOLO(yolov8n.pt) metrics_baseline baseline_pretrained.val( datacoco.yaml, imgsz640, batch32, device0, save_jsonTrue, projectruns/eval, namebaseline_yolov8n_pretrained ) print(f基线预训练模型 mAP50-95: {metrics_baseline.box.map:.4f}) # 或者从头训练一个 YOLOv8n 作为基线更公平的比较 # 只需将 distill_train.py 中的 --teacher_model 和 --distill 参数去掉重新训练。3. 结果对比与分析 假设我们得到以下结果数值为示例实际运行会有差异基线 YOLOv8n (从头训练)mAP50-95 37.2%蒸馏后 YOLOv8nmAP50-95 42.5%提升分析绝对提升42.5% - 37.2% 5.3% mAP。相对提升(42.5 - 37.2) / 37.2 ≈14.2%。速度对比推理速度FPS理论上应与基线 YOLOv8n 几乎一致因为网络结构未变。你可以使用model.predict(...)并计时来验证。这个提升是显著的意味着我们成功地将大模型的知识“转移”给了小模型使其在精度上更接近大模型同时保持了小模型的推理效率。5. 常见问题与排查思路在实践知识蒸馏的过程中你可能会遇到以下问题。这里提供一些排查思路。问题现象可能原因解决思路训练报错KeyError: ‘teacher_model’Ultralytics 版本过低不支持蒸馏参数。升级ultralytics到最新版本pip install -U ultralytics。确保版本 8.0.145。蒸馏损失 (train/distill_loss) 不下降或为 NaN1. 温度参数temperature设置不当如太小。2. 蒸馏损失权重distill_weight过大导致数值不稳定。3. 教师模型输出异常如全零。1. 尝试增大temperature(如 10.0)。2. 降低distill_weight(如从 1.0 降到 0.3)。3. 检查教师模型是否加载成功并手动验证其前向传播。学生模型性能反而下降1. 教师模型与学生模型任务差异太大。2.distill_weight过高学生过度模仿教师而忽略了真实标签。3. 训练轮数不足或学习率设置不当。1. 确保教师和学生模型是在同类任务上预训练的如都是 COCO 目标检测。2. 调整distill_weight找到一个平衡点如 0.3-0.7。3. 增加训练轮数epochs或调整学习率调度策略。训练速度非常慢1. 同时加载了两个大模型显存/内存不足。2.teacher_imgsz设置得比imgsz大很多。3.batch_size过大。1. 检查 GPU 使用情况 (nvidia-smi)。尝试减小batch_size。2. 将teacher_imgsz设置为与imgsz相同或更小。3. 使用梯度累积来模拟更大的 batch。mAP 提升不明显1. 教师模型本身在该数据集上表现不佳。2. 学生模型容量太小无法吸收教师的知识。3. 数据增强过于强烈干扰了学习。1. 换一个更强的教师模型或在目标任务上微调教师模型。2. 尝试稍大的学生模型如yolov8s。3. 减弱数据增强强度如降低hsv_h,hsv_s,hsv_v。GPU 显存溢出 (OOM)1.batch_size太大。2.imgsz或teacher_imgsz太大。3. 同时保存了过多中间结果。1. 首要降低batch_size。2. 降低输入图像尺寸。3. 在训练命令中设置cacheFalse(禁用数据集缓存)。6. 最佳实践与工程建议为了让知识蒸馏在实际项目中发挥最大效用以下是一些经过验证的最佳实践。6.1 教师模型的选择与准备领域适配如果您的任务是一个特定领域如医疗影像、遥感最好使用在该领域数据上微调过的教师模型而不是通用的 COCO 预训练模型。教师越“专业”学生越能学到有用的知识。教师不一定最大有时一个中等大小但训练得非常充分的模型比一个超大但训练不充分的模型是更好的教师。教师模型的质量比其绝对大小更重要。冻结教师务必确保在蒸馏训练过程中教师模型的权重是冻结的不更新。Ultralytics 框架默认会处理这一点。6.2 超参数调优策略蒸馏效果对超参数敏感建议进行系统性的调优网格搜索对distill_weight(如 [0.1, 0.3, 0.5, 0.7, 0.9]) 和temperature(如 [1, 2, 4, 10]) 进行组合实验。分阶段训练第一阶段使用较高的distill_weight(如 0.7) 和较高的temperature(如 4.0)让学生快速模仿教师的整体输出分布。第二阶段降低distill_weight(如 0.3) 和temperature(如 2.0)让学生更关注真实标签和细节。学习率调整由于蒸馏任务相对复杂初始学习率lr0可以比从头训练稍低一些并使用cosine或linear衰减策略。6.3 训练技巧与监控使用验证集早停监控验证集 mAP如果连续多个 epoch 没有提升则提前停止训练防止过拟合。保存最佳检查点YOLOv8 默认会保存验证集指标最好的模型为best.pt。可视化损失曲线密切关注train/box_loss和train/distill_loss的曲线。理想情况下两者都应平稳下降。如果蒸馏损失震荡剧烈可能需要降低其权重或学习率。混合精度训练确保fp16True参数被设置如果 GPU 支持这可以显著加快训练速度并减少显存占用。6.4 部署与性能验证导出为部署格式训练完成后使用model.export(formatonnx)或model.export(formatengine)将模型导出为 ONNX 或 TensorRT 格式以便在边缘设备上高效部署。基准测试在目标部署硬件上对蒸馏前后的模型进行严格的 FPS 和精度测试量化其“精度-速度”权衡的改善。集成测试将蒸馏后的模型集成到完整的应用流水线中确保其端到端的性能符合预期。通过遵循上述步骤和建议你可以系统地将知识蒸馏技术应用到你的 YOLO 项目中让小模型在资源受限的环境下也能发挥出接近大模型的性能为你的产品带来实实在在的竞争力提升。