yolov26改进 | 科研篇 | 利用训练好权重文件计算YOLOv26的FPS、推理每张图片的平均时间(科研必备)

开始正文前,先向大家推荐我的YOLO专栏系列。本人持续更新 YOLOv8、YOLO11、YOLO26 等热门模型,内容覆盖图像分类、目标检测、实例分割、多目标跟踪、姿态估计与关键点检测,重点讲解 小目标检测、注意力机制、特征融合、损失函数改进、自定义数据集训练、消融实验及论文代码复现。同时分享如何使用 OpenAI Codex辅助撰写论文、配置实验环境、调试项目、改进模型和分析实验结果。 专栏目前正在进行限时优惠,每周更新 5–7篇最新论文机制、YOLO改进方法和实战教程。订阅后可获得包含本人全部改进方案的代码与配置文件,并加入专属技术交流群。我也会定期在群内分享 YOLO论文选题、创新点设计、实验方案、论文写作与投稿发表经验,欢迎大家订阅交流!


一、本文介绍

本文给大家带来的改进机制是利用我们训练好的YOLOv26权重文件计算FPS同时打印每张图片所利用的平均时间,模型大小(以MB为单位),同时支持batch_size功能的选择,对于轻量化模型的读者来说,本文的内容对你一定有帮助,可以清晰帮你展示出模型速度性能的提升以及轻量化的效果(模型大小),对于以提高精度为目的的读者本文也能够帮助大家展示出现阶段的模型速度指标。所以本文的内容是十分有用的机制,对于大家发表论文来说,下面的图片为运行后的效果可以看到,该有的指标均已打印(本文内容为我独家创新,全网无第二份)

欢迎大家订阅我的专栏一起学习YOLO! 


目录

一、本文介绍

二、核心代码 

三、参数讲解

四、效果展示 

五、本文总结


专栏链接:YOLOv26有效涨点专栏包含:Conv、注意力机制、主干/Backbone、损失函数、优化器、后处理等改进机制

二、核心代码 

下面的为核心代码,我们将其复制粘贴到我们的ultralytics仓库的最外层目录下即可,创建一个py文件存放进去。

import warnings

warnings.filterwarnings("ignore")

import argparse
import logging
import os
import time

import numpy as np
import torch
from tqdm import tqdm
from ultralytics.nn.tasks import load_checkpoint
from ultralytics.utils.torch_utils import select_device


# 日志配置
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

LOGGER = logging.getLogger(__name__)


def get_weight_size(path):
    """获取模型权重文件大小,单位 MiB。"""
    try:
        size = os.path.getsize(path)
        return f"{size / (1024 ** 2):.1f}"
    except OSError as error:
        LOGGER.warning("无法获取权重文件大小:%s", error)
        return "N/A"


def synchronize_device(device):
    """同步 CUDA 操作。"""
    if device.type == "cuda":
        torch.cuda.synchronize(device)


@torch.inference_mode()
def warmup_model(model, device, example_inputs, iterations=200):
    """模型预热。"""
    if iterations <= 0:
        LOGGER.info("模型预热已关闭。")
        return

    LOGGER.info("Beginning warmup...")

    for _ in tqdm(range(iterations), desc="Warmup", dynamic_ncols=True):
        model(example_inputs)

    synchronize_device(device)


@torch.inference_mode()
def test_model_latency(model, device, example_inputs, iterations=1000):
    """测试模型纯前向传播延迟。"""
    LOGGER.info("Testing latency...")

    latency_results = np.empty(iterations, dtype=np.float64)

    for index in tqdm(range(iterations), desc="Latency Test", dynamic_ncols=True):
        # CUDA 默认异步执行,因此计时前需要同步
        synchronize_device(device)

        start_time = time.perf_counter()

        model(example_inputs)

        # 等待当前推理完全执行结束
        synchronize_device(device)

        end_time = time.perf_counter()

        latency_results[index] = end_time - start_time

    return {
        "mean": float(np.mean(latency_results)),
        "median": float(np.median(latency_results)),
        "std": float(np.std(latency_results)),
        "min": float(np.min(latency_results)),
        "max": float(np.max(latency_results))
    }


def main(opt):
    """模型性能测试主函数。"""

    # 参数检查
    if not opt.weights.lower().endswith(".pt"):
        raise ValueError(f"模型权重必须是 .pt 文件:{opt.weights}")

    if opt.batch <= 0:
        raise ValueError("batch 必须大于 0")

    if len(opt.imgs) != 2:
        raise ValueError("--imgs 必须包含高度和宽度,例如 [640, 640]")

    if opt.imgs[0] <= 0 or opt.imgs[1] <= 0:
        raise ValueError("输入图像尺寸必须大于 0")

    if opt.warmup < 0:
        raise ValueError("warmup 不能小于 0")

    if opt.testtime <= 0:
        raise ValueError("testtime 必须大于 0")

    # 选择推理设备
    device = select_device(opt.device)

    # FP16 只支持 CUDA
    if opt.half and device.type != "cuda":
        raise ValueError("FP16 仅支持 CUDA GPU,请使用 device='0' 或关闭 half")

    # 固定输入尺寸时启用 cuDNN benchmark
    if device.type == "cuda":
        torch.backends.cudnn.benchmark = True

    LOGGER.info("Loading model: %s", opt.weights)

    # Ultralytics 8.4.46 模型加载方式
    model, _ = load_checkpoint(
        opt.weights,
        device=device,
        fuse=True
    )

    model.eval()

    # 设置模型和输入精度
    if opt.half:
        model.half()
        input_dtype = torch.float16
        precision = "FP16"
    else:
        model.float()
        input_dtype = torch.float32
        precision = "FP32"

    # 创建随机测试输入
    example_inputs = torch.randn(
        opt.batch,
        3,
        opt.imgs[0],
        opt.imgs[1],
        device=device,
        dtype=input_dtype
    )

    LOGGER.info(
        "Benchmark configuration | Device: %s | Batch: %d | Input: %dx%d | Precision: %s",
        device,
        opt.batch,
        opt.imgs[0],
        opt.imgs[1],
        precision
    )

    # 模型预热
    warmup_model(
        model=model,
        device=device,
        example_inputs=example_inputs,
        iterations=opt.warmup
    )

    # 正式测速
    latency = test_model_latency(
        model=model,
        device=device,
        example_inputs=example_inputs,
        iterations=opt.testtime
    )

    # 一次模型前向传播处理 opt.batch 张图片
    batch_fps = 1.0 / latency["mean"]
    image_fps = opt.batch / latency["mean"]

    LOGGER.info(
        "\n"
        "================ 测速结果 ================\n"
        "模型权重       : %s\n"
        "权重大小       : %s MiB\n"
        "运行设备       : %s\n"
        "Batch Size     : %d\n"
        "输入尺寸       : %dx%d\n"
        "推理精度       : %s\n"
        "平均延迟       : %.3f ms/batch\n"
        "中位延迟       : %.3f ms/batch\n"
        "延迟标准差     : %.3f ms\n"
        "最小延迟       : %.3f ms\n"
        "最大延迟       : %.3f ms\n"
        "Batch FPS      : %.1f batch/s\n"
        "Image FPS      : %.1f images/s\n"
        "==========================================",
        opt.weights,
        get_weight_size(opt.weights),
        device,
        opt.batch,
        opt.imgs[0],
        opt.imgs[1],
        precision,
        latency["mean"] * 1000,
        latency["median"] * 1000,
        latency["std"] * 1000,
        latency["min"] * 1000,
        latency["max"] * 1000,
        batch_fps,
        image_fps
    )

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Test YOLOv26 model performance.")
    parser.add_argument("--weights", type=str, default="yolo26n.pt", help="trained weights path")
    parser.add_argument("--batch", type=int, default=1, help="batch size")
    parser.add_argument("--imgs", nargs="+", type=int, default=[640, 640], help="image sizes [height, width]")
    parser.add_argument("--device", type=str, default="0", help="CUDA device, e.g. 0 or cpu")
    parser.add_argument("--warmup", type=int, default=200, help="warmup iterations")
    parser.add_argument("--testtime", type=int, default=1000, help="test iterations for latency")
    parser.add_argument("--half", action="store_true", default=True, help="use FP16 mode for inference")
    opt = parser.parse_args()

    main(opt)


三、参数讲解

本文涉及到的参数共有如下。

参数讲解如下 

1weights对应的权重文件地址
2batch计算多少个图片的FPS
3imgs图片的大小默认为640
4device推理的设备选择,默认为GPU:0
5warmup预测轮次,预热阶段目的是让模型运行在一个更稳定的状态,提高模型推理性能
6testtime参数定义了进行性能评估时执行的推理轮次数,这个参数使得性能测试更加准确和可靠。通过在足够多的轮次上测量推理时间,可以减少偶然因素的影响,并获得一个更加稳定和准确的性能指标
7half推理精度这个不多介绍了大家都懂,FPS16更快


四、效果展示 

下面是效果展示,可以看到所有的参数均已打印。


五、本文总结 

到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv26改进有效涨点专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充,如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~

专栏链接:YOLOv26有效涨点专栏包含:Conv、注意力机制、主干/Backbone、损失函数、优化器、后处理等改进机制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Snu77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值