当前位置: 首页 > news >正文

如何测试模型推理性能:从零开始的Python指南

如何测试模型推理性能:从零开始的Python指南

    • 什么是模型推理性能?
    • 测试模型推理性能的步骤
      • 1. 监测内存使用情况
      • 2. 测试模型吞吐量
    • 运行测试
    • 总结

在机器学习和深度学习中,模型的推理性能是一个非常重要的指标。它可以帮助我们了解模型在实际应用中的表现,尤其是在处理大规模数据时。本文将带你一步步了解如何测试模型的推理性能,并使用Python编写简单的代码来实现这一目标。

什么是模型推理性能?

模型推理性能主要关注两个方面:

  1. 内存使用情况:模型在推理过程中占用的内存大小。
  2. 模型吞吐量:模型在单位时间内能够处理的token数量。吞吐量又分为两个阶段:
    • Prefill阶段:模型预先计算并缓存一部分自注意力计算的过程。
    • Decode阶段:模型在自回归阶段不断生成新token的过程。

测试模型推理性能的步骤

我们将使用Python编写两个脚本:monitor.pybenchmark.pymonitor.py 用于监测内存使用情况,benchmark.py 用于测试模型的吞吐量。

1. 监测内存使用情况

首先,我们需要编写一个脚本来监测模型推理时的内存使用情况。我们将使用 psutil 库来实现这一功能。

import psutil
import time
import os
import signal
import sys
import atexit
import jsoncurrent_pid = os.getpid()
print(f"当前进程pid号为: {current_pid}")monitored = sys.argv[1]
print(f"需要监测的进程为: {monitored}")
target_pid = None# 清除残留进程
for proc in psutil.process_iter(['pid', 'name', 'cmdline']):if monitored in proc.info['cmdline'] and proc.pid != current_pid:print(f"残留进程为: {proc.pid}")proc.kill()print("残留进程清除完成")print("\r\n")
print("寻找指定进程,请打开吞吐量测试脚本,并在吞吐量测试完毕后关闭此脚本:")# 寻找目标进程
while not target_pid:for proc in psutil.process_iter(['pid', 'name', 'cmdline']):if monitored in proc.info['cmdline'] and proc.pid != current_pid:target_pid = proc.pidbreakif not target_pid:print("未找到指定进程")time.sleep(1)print("\r\n")
print(f"已找到指定进程pid号为: {target_pid}")
process = psutil.Process(target_pid)
process_cmdline = process.cmdline()
print(f"pid对应名称为 {process_cmdline}")max_memory_stats = {"max_rss": 0,"max_vms": 0
}# 导出内存使用情况到JSON文件
def write_memory_max_to_json():with open('memory_results.json', 'w') as report_file:json.dump(max_memory_stats, report_file, indent=2)print("\n已成功将内存使用情况保存至 'memory_results.json' 文件中.")atexit.register(write_memory_max_to_json)  # 在进程结束时保存结果# 实时监测内存使用情况
while 1:time.sleep(0.1)mem_info = process.memory_info()rss = mem_info.rss / 1024 ** 2vms = mem_info.vms / 1024 ** 2max_memory_stats["max_rss"] = max(max_memory_stats["max_rss"], rss)max_memory_stats["max_vms"] = max(max_memory_stats["max_vms"], vms)print(f"Current RSS Memory: {rss:.2f} MB | Current VMS Memory: {vms:.2f} MB")print(f"Max RSS Memory: {max_memory_stats['max_rss']:.2f} MB | Max VMS Memory: {max_memory_stats['max_vms']:.2f} MB\n")

2. 测试模型吞吐量

接下来,我们编写一个脚本来测试模型的吞吐量。我们将使用 transformers 库来加载模型并进行推理。

import torch
import time
from transformers import AutoModelForCausalLM, AutoTokenizer
import json
import osos.environ["CUDA_VISIBLE_DEVICES"] = "-1"  # 使用CPU进行推理# 加载分词器和模型
print("加载分词器\r\n")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B", trust_remote_code=True)
print("加载模型\r\n")
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-0.5B", device_map="auto", trust_remote_code=True).eval()
print("模型加载完成\r\n")# 加载指定文本作为prompt
print("加载prompt\r\n")
with open('prompt.txt', 'r', encoding='utf-8') as file:prompt = file.read()# 对prompt进行分词
print("分词器分词\r\n")
inputs = tokenizer(prompt, return_tensors='pt')
inputs = inputs.to(model.device)# Prefill阶段吞吐量测试
print("prefill阶段吞吐量测试:\r\n")
batch_size = 1  # 单个prompt,批次大小为1
total_prompts = 10  # 测试10次
total_tokens = inputs['input_ids'].shape[1]  # token数量start_time_prefill = time.time()
for _ in range(total_prompts):with torch.no_grad():  # 关闭梯度计算以提高推理性能outputs = model(**inputs)
end_time_prefill = time.time()
elapsed_time_prefill = end_time_prefill - start_time_prefill  # 推理总时长
throughput_prefill = total_prompts * total_tokens / elapsed_time_prefill  # prefill吞吐量,每秒处理的token数
print(f"tokens总数为 {total_tokens}")
print(f"测试次数为 {total_prompts}")
print(f"总时长为 {elapsed_time_prefill}")
print(f"模型prefill阶段的吞吐量: {throughput_prefill:.2f} tokens/s\r\n")
print("prefill阶段吞吐量测试完成\r\n")# Decode阶段吞吐量测试
print("decode阶段吞吐量测试:\r\n")
max_new_tokens = 50  # 要推理的新token总数
total_prompts = 10  # 测试10次start_time_decode = time.time()
for _ in range(total_prompts):with torch.no_grad():  # 关闭梯度计算以提高推理性能outputs = model.generate(**inputs, min_new_tokens=max_new_tokens, max_new_tokens=max_new_tokens)print(f"请确保生成new_tokens为50 {total_tokens} --> {outputs.shape}")
end_time_decode = time.time()
elapsed_time_decode = end_time_decode - start_time_decode  # 推理总时长
throughput_decode = total_prompts * max_new_tokens / elapsed_time_decode  # decode吞吐量,每秒生成的新token数
print(f"生成新tokens数为 {max_new_tokens}")
print(f"测试次数为 {total_prompts}")
print(f"总时长为 {elapsed_time_decode}")
print(f"模型decode的吞吐量: {throughput_decode:.2f} tokens/s\r\n")
print("decode阶段吞吐量测试完成\r\n")# 保存吞吐量测试结果
results = {"prefill_throughput": throughput_prefill,"decode_throughput": throughput_decode
}
with open('throughput_results.json', 'w') as output_file:json.dump(results, output_file, indent=4)
print("\n已成功将吞吐量结果保存至 'throughput_results.json' 文件中.")

运行测试

  1. 首先,在命令行中运行 monitor.py 脚本,并指定要监测的脚本为 benchmark.py

    python monitor.py benchmark.py
    
  2. 接着,打开一个新的终端窗口,运行 benchmark.py 脚本:

    python benchmark.py
    
  3. 等待 benchmark.py 运行结束后,monitor.py 会自动结束,并将内存使用情况和吞吐量测试结果分别保存到 memory_results.jsonthroughput_results.json 文件中。

总结

通过以上步骤,你可以轻松地测试模型的推理性能。无论是内存使用情况还是模型吞吐量,这些指标都能帮助你更好地了解模型的实际表现。希望这篇博客能帮助你入门模型性能测试,并为你未来的项目提供有价值的参考。

相关文章:

如何测试模型推理性能:从零开始的Python指南

如何测试模型推理性能:从零开始的Python指南 什么是模型推理性能?测试模型推理性能的步骤1. 监测内存使用情况2. 测试模型吞吐量 运行测试总结 在机器学习和深度学习中,模型的推理性能是一个非常重要的指标。它可以帮助我们了解模型在实际应用…...

我们来学activiti -- bpmn

bpmn 题记bpmn结余 题记 在《Activiti很难学》提到学习知识点需要面对的思想钢印问题 按常见步骤,先展示下官方的客套话 BPMN(Business Process Model and Notation)是一种业务流程建模符号, 它是一种图形化的语言,用…...

【每日学点鸿蒙知识】节点析构问题、区分手机和pad、 Navigation路由问题、Tabs组件宽度、如何监听Map

1、HarmonyOS 只调用根节点的dispose,是否其下的子节点都能析构掉还是需要遍历子节点,都执行dispose才能正常析构? 前端持有引用关系的需要dispose,new出来的builderNode和FrameNode也需要dispose。只调用根节点的dispose,无法保证其下的子节…...

敏捷测试文化的转变

敏捷文化是敏捷测试转型的基础,只有具备敏捷文化的氛围,对组织架构、流程和相关测试实践的调整才能起作用。在前面的敏捷测试定义中,敏捷测试是遵从敏捷软件开发原则的一种测试实践,这意味着敏捷的价值观。 此外,从传…...

如何配置线程池参数,才能创建性能最好、最稳定的Spring异步线程池?

配置性能最好、最稳定的Spring异步线程池,需要综合考虑业务场景、硬件资源(CPU核心数、内存等)、并发量、任务特性(CPU密集型、IO密集型等)以及线程池参数。 以下是优化线程池配置的关键点及代码示例: 线程…...

【时间之外】IT人求职和创业应知【80】-特殊日子

目录 北京冬季招聘会 OpenAI CEO炮轰马斯克 英伟达推出全新AI芯片B300 莫欢喜,总成空。本周必须要谨行慎言。 感谢所有打开这个页面的朋友。人生不如意,开越野车去撒野,会害了自己,不如提升自己。提升自己的捷径就是学习和思考…...

Vue中接入萤石等直播视频(更新中ing)

一、萤石: 1. 萤石云开发文档: https://open.ys7.com/help/31 2、安装: npm install ezuikit-js --save 3、在文件中引用:import EZUIKit from ezuikit-js 4、具体代码: 获取accessToken:https://open.…...

如何学习、使用Ai,才能跟上时代的步伐?

目录 1. 打好基础:理解AI的核心概念 2. 学习AI的核心领域 3. 实践:动手做项目,积累经验 4. 利用AI工具提升工作效率 5. 培养AI思维与批判性思维 6. 关注AI领域的最新研究与趋势 7. 培养跨学科能力 总结: 在AI时代&#xf…...

RabbitMQ中的异步Confirm模式:提升消息可靠性的利器

在现代分布式系统中,消息队列(Message Queue)扮演着至关重要的角色,它能够解耦系统组件、提高系统的可扩展性和可靠性。RabbitMQ作为一款广泛使用的消息队列中间件,提供了多种机制来确保消息的可靠传递。其中&#xff…...

Linux(Centos 7.6)目录结构详解

Linux(Centos 7.6)是一个操作系统,其核心设计理念是将一切资源抽象为文件,即一切皆文件。比如系统中的硬件设备硬盘、网络接口等都被视为文件。Windows系统一般是分为C、D、E盘。而Linux(Centos 7.6)是以斜线"/"作为文件系统的开始目录&#x…...

upload-labs关卡记录8

黑名单过滤,同时不能进行双写,大小写,特殊可解析后缀,.htaccess,都不能。点击提示发现: 禁止上传所有可解析后缀,抓包试试: 抓包加空格发现也不能绕过,看源码分析吧: $i…...

GXUOJ-算法-第二次作业

1.矩阵连&#xff08;链&#xff09;乘 问题描述 GXUOJ | 矩阵连乘 代码解答 #include<bits/stdc.h> using namespace std;const int N50; int m[N][N]; int p[N]; int n;int main(){cin>>n;//m[i][j] 存储的是从第 i 个矩阵到第 j 个矩阵这一段矩阵链相乘的最小…...

Gavin Wood 的 Polkadot 2024 年度回顾:技术突破与未来的无限可能

原文&#xff1a;https://medium.com/polkadot-network/polkadot-roundup-mmxxiv-8d3e880dd637 作者&#xff1a;Gavin Wood 编译&#xff1a;OneBlock &#x1f384; 各位波卡生态的 Buidler 们&#xff0c;圣诞快乐&#xff01;在这个充满节日气氛的时刻&#xff0c;很高兴与…...

AduSkin、WPF-UI、Prism:WPF 框架全解析与应用指南

摘要: 本文深入探讨了 AduSkin、WPF-UI、Prism 这三个在 WPF 开发领域极具影响力的框架。详细阐述了每个框架的特点、核心功能、安装与配置过程,并通过丰富的代码示例展示其在实际应用场景中的使用方式,包括界面美化、导航与模块管理等方面。同时对它们的优势与局限性进行了…...

【超详细】Git的基本概念和基本使用方式

Git是程序开发中非常重要的工具&#xff0c;是一种分布式版本控制系统&#xff0c;可用于管理和追踪软件开发过程中的变化。那么关于Git的基本操作你知道吗&#xff1f;下面是Git的基本概念和使用方式的解释&#xff1a; 仓库&#xff08;Repository&#xff09;&#xff1a;Gi…...

【数据结构】单链表的使用

单链表的使用 1、基本概念2、链表的分类3、链表的基本操作a、单链表节点设计b、单链表初始化c、单链表增删节点**节点头插&#xff1a;****节点尾插&#xff1a;****新节点插入指定节点后&#xff1a;**节点删除&#xff1a; d、单链表修改节点e、单链表遍历&#xff0c;并打印…...

外键约束的应用层维护

1.前言 一般来说 对于不同表格之间的属性约束 我们通常直接使用数据库已经实现好的外键来完成 但是数据库底层实现的外键他的性能很差 这是因为在执行数据库修改操作时 他需要遍历其他所有的表来找出其中可能相关联的属性 一并进行数据库修改(应用层的维护则只需要遍历所有关联…...

springboot整合log4j2日志框架1

目录 一 log4j基本知识 1.1 log4j的日志级别 1.2 log4j的日志文件结构* 1.2.1 概述 1.2.2 详解 1.3 log4j的日志格式化api 1.3.1 api详解 1.3.2 演示案例 1.3.3 演示案例 1.4 log4j中onmatch和onmismatch的区别* 1.4.1 案例 1.4.2 onmatch的api 1.5 logback&#x…...

06 - Django 视图view

HttpRequest 和 HttpResponse Django中的视图主要用来接受Web请求&#xff0c;并做出响应。 视图的本质就是一个Python中的函数 视图的响应分为两大类 以Json数据形式返回(JsonResponse)以网页的形式返回 重定向到另一个网页 (HttpResponseRedirect)错误视图(4XX,5XX) (Htt…...

基于云计算的资源管理系统

基于云计算的资源管理系统是一种将云计算技术与资源管理技术相结合&#xff0c;以实现资源高效利用和管理的系统。以下是对该系统的详细分析&#xff1a; 一、系统概述 云计算是一种基于网络的计算模式&#xff0c;通过将计算资源和数据存储在云端服务器上&#xff0c;使用户…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...