Qwen1.5-1.8B GPTQ系统资源监控Python脚本实现GPU显存与算力实时查看当你兴致勃勃地部署好Qwen1.5-1.8B GPTQ模型准备让它大展身手时有没有遇到过这样的困惑模型推理时电脑突然卡顿或者程序莫名其妙地崩溃了你可能会想是显存不够了还是GPU算力到顶了光靠感觉可不行我们需要一双“眼睛”来实时看清GPU到底在忙些什么。今天我就带你写一个简单的Python监控脚本。它就像给你的GPU装上一个实时仪表盘显存用了多少、算力负载多大、温度高不高一目了然。这对于调试模型性能、排查运行故障或者只是想了解自己硬件的“工作状态”都非常有用。1. 准备工作环境与工具在开始写代码之前我们需要准备好“工具箱”。整个过程非常简单几乎不会遇到什么坑。1.1 确认你的环境首先确保你已经在运行Qwen1.5-1.8B GPTQ模型的环境里。这个环境通常已经安装了PyTorch或TensorFlow等深度学习框架。我们的监控脚本将独立于模型运行所以不用担心会影响现有的项目。你可以打开终端或命令提示符输入python --version来确认Python环境。建议使用Python 3.7或更高版本。1.2 安装核心监控库我们需要一个能与NVIDIA GPU“对话”的库来获取硬件信息。这里推荐使用pynvml它是NVIDIA官方管理库NVML的Python封装轻量且功能直接。打开终端用pip安装它pip install pynvml通常这就够了。pynvml库本身很小安装很快。安装成功后我们就可以在Python代码里导入它并开始查询GPU信息了。2. 编写基础监控脚本让我们从最简单的功能开始一次性获取并打印出所有GPU的当前状态。新建一个Python文件比如叫做gpu_monitor_simple.py。2.1 连接GPU并获取基本信息首先我们需要初始化pynvml库并获取机器上有多少块GPU。import pynvml def get_gpu_info(): 获取并打印所有GPU的基本信息。 try: # 初始化NVML库 pynvml.nvmlInit() print(NVML初始化成功。) # 获取GPU设备数量 device_count pynvml.nvmlDeviceGetCount() print(f系统中发现 {device_count} 块GPU。\n) # 遍历每一块GPU for i in range(device_count): print(f GPU {i} 信息 ) # 获取第i块GPU的句柄可以理解为它的操作手柄 handle pynvml.nvmlDeviceGetHandleByIndex(i) # 1. 获取GPU名称 name pynvml.nvmlDeviceGetName(handle) print(f 设备名称: {name.decode(utf-8) if isinstance(name, bytes) else name}) # 2. 获取显存信息单位字节 mem_info pynvml.nvmlDeviceGetMemoryInfo(handle) total_mem mem_info.total / 1024**3 # 转换为GB used_mem mem_info.used / 1024**3 free_mem mem_info.free / 1024**3 print(f 显存总量: {total_mem:.2f} GB) print(f 已用显存: {used_mem:.2f} GB) print(f 剩余显存: {free_mem:.2f} GB) print(f 显存使用率: {used_mem/total_mem*100:.1f}%) # 3. 获取GPU利用率主要是计算单元的使用率 utilization pynvml.nvmlDeviceGetUtilizationRates(handle) print(f GPU计算利用率: {utilization.gpu}%) # 注意显存控制器利用率通常不是我们关注的重点 # print(f 显存控制器利用率: {utilization.memory}%) # 4. 获取GPU温度 temperature pynvml.nvmlDeviceGetTemperature(handle, pynvml.NVML_TEMPERATURE_GPU) print(f GPU当前温度: {temperature}°C) # 5. 获取GPU当前功耗和功耗上限如果支持 try: power_usage pynvml.nvmlDeviceGetPowerUsage(handle) / 1000.0 # 转换为瓦特 power_limit pynvml.nvmlDeviceGetPowerManagementLimit(handle) / 1000.0 print(f 当前功耗: {power_usage:.1f} W) print(f 功耗上限: {power_limit:.1f} W) except pynvml.NVMLError_NotSupported: print( 功耗信息: 该设备不支持或未启用) print() # 空行分隔每块GPU信息 # 最后记得关闭NVML库 pynvml.nvmlShutdown() except pynvml.NVMLError as error: print(f访问GPU时出错: {error}) except Exception as e: print(f发生未知错误: {e}) if __name__ __main__: get_gpu_info()把这段代码保存并运行你就能在终端看到类似下面的输出NVML初始化成功。 系统中发现 1 块GPU。 GPU 0 信息 设备名称: NVIDIA GeForce RTX 4090 显存总量: 24.00 GB 已用显存: 1.52 GB 剩余显存: 22.48 GB 显存使用率: 6.3% GPU计算利用率: 5% GPU当前温度: 45°C 当前功耗: 45.3 W 功耗上限: 450.0 W看是不是很简单你现在已经能拿到GPU最核心的几个指标了。当你的Qwen模型在推理时再运行这个脚本就能看到显存和利用率的明显变化。3. 实现实时监控与日志记录一次性查看固然有用但我们更关心模型运行过程中的变化趋势。比如显存是不是在缓慢泄漏推理峰值时算力能不能跟上这就需要实时监控。3.1 创建周期性监控循环我们改造一下脚本让它能每隔几秒就检查一次状态并持续运行。新建一个文件gpu_monitor_realtime.py。import pynvml import time import sys def monitor_gpu(interval_sec2, duration_sec30): 实时监控GPU状态。 :param interval_sec: 监控间隔单位秒 :param duration_sec: 总监控时长单位秒。设为0则无限循环。 try: pynvml.nvmlInit() device_count pynvml.nvmlDeviceGetCount() print(f开始监控 {device_count} 块GPU每 {interval_sec} 秒刷新一次。按 CtrlC 终止。\n) start_time time.time() iteration 0 # 打印表头 header f{时间:10} | {GPU:4} | {显存使用(GB):15} | {使用率(%):12} | {温度(°C):10} print(header) print(- * len(header)) while True: current_time time.time() - start_time iteration 1 # 如果设置了监控时长且已超时则退出 if duration_sec 0 and current_time duration_sec: print(f\n监控时长 ({duration_sec}秒) 已到停止监控。) break for i in range(device_count): handle pynvml.nvmlDeviceGetHandleByIndex(i) # 获取信息 mem_info pynvml.nvmlDeviceGetMemoryInfo(handle) used_mem_gb mem_info.used / 1024**3 utilization pynvml.nvmlDeviceGetUtilizationRates(handle) gpu_util utilization.gpu temperature pynvml.nvmlDeviceGetTemperature(handle, pynvml.NVML_TEMPERATURE_GPU) # 格式化输出 time_str f{current_time:6.1f}s gpu_str f{i} mem_str f{used_mem_gb:5.2f} / {mem_info.total/1024**3:5.2f} util_str f{gpu_util:3d} temp_str f{temperature:3d} print(f{time_str} | {gpu_str:4} | {mem_str:15} | {util_str:12} | {temp_str:10}) # 控制台输出刷新让数据在同一行区域更新 if iteration % 10 ! 0 or duration_sec 0: # 每10次清屏一次避免无限滚动 sys.stdout.write(f\033[{device_count}A) # 光标上移device_count行 else: print(\n - * len(header)) # 每10次打印一个分隔线增强可读性 time.sleep(interval_sec) except KeyboardInterrupt: print(\n\n监控被用户中断。) except pynvml.NVMLError as error: print(f\n访问GPU时出错: {error}) except Exception as e: print(f\n发生未知错误: {e}) finally: try: pynvml.nvmlShutdown() except: pass if __name__ __main__: # 示例监控30秒每2秒刷新一次 monitor_gpu(interval_sec2, duration_sec30)运行这个脚本你会看到一个不断更新的控制台输出清晰地展示了GPU状态随时间的变化。这对于观察模型加载、推理预热、持续生成等不同阶段的资源消耗模式特别有帮助。3.2 将监控数据记录到文件光在屏幕上看还不够我们经常需要把数据保存下来用于事后分析或生成报告。我们来增加日志功能。import pynvml import time import csv from datetime import datetime def monitor_and_log_gpu(log_filegpu_log.csv, interval_sec5): 监控GPU状态并记录到CSV文件。 :param log_file: 日志文件名 :param interval_sec: 记录间隔 try: pynvml.nvmlInit() device_count pynvml.nvmlDeviceGetCount() print(f开始监控并记录到 {log_file}每 {interval_sec} 秒记录一次。按 CtrlC 终止。) # 准备CSV文件并写入表头 with open(log_file, modew, newline, encodingutf-8) as f: writer csv.writer(f) # 构建表头 headers [timestamp, gpu_id, gpu_name, mem_used_gb, mem_total_gb, gpu_util_percent, temperature_c] # 可以尝试添加功耗但非必需 try: handle0 pynvml.nvmlDeviceGetHandleByIndex(0) pynvml.nvmlDeviceGetPowerUsage(handle0) # 测试是否支持 headers.extend([power_usage_w, power_limit_w]) power_supported True except pynvml.NVMLError: power_supported False writer.writerow(headers) f.flush() # 立即写入表头 print(f记录字段: {, .join(headers)}) while True: timestamp datetime.now().isoformat(timespecseconds) for i in range(device_count): handle pynvml.nvmlDeviceGetHandleByIndex(i) # 获取静态信息只需一次 if i 0 and gpu_name not in locals(): # 简单缓存名字 gpu_name pynvml.nvmlDeviceGetName(handle) if isinstance(gpu_name, bytes): gpu_name gpu_name.decode(utf-8) # 获取动态信息 mem_info pynvml.nvmlDeviceGetMemoryInfo(handle) used_mem_gb mem_info.used / 1024**3 total_mem_gb mem_info.total / 1024**3 utilization pynvml.nvmlDeviceGetUtilizationRates(handle) gpu_util utilization.gpu temperature pynvml.nvmlDeviceGetTemperature(handle, pynvml.NVML_TEMPERATURE_GPU) # 构建一行数据 row_data [timestamp, i, gpu_name, f{used_mem_gb:.3f}, f{total_mem_gb:.3f}, gpu_util, temperature] # 添加功耗信息 if power_supported: try: power_usage pynvml.nvmlDeviceGetPowerUsage(handle) / 1000.0 power_limit pynvml.nvmlDeviceGetPowerManagementLimit(handle) / 1000.0 row_data.extend([f{power_usage:.1f}, f{power_limit:.1f}]) except: row_data.extend([N/A, N/A]) writer.writerow(row_data) f.flush() # 确保数据写入磁盘 print(f[{timestamp}] 已记录 {device_count} 块GPU状态。) time.sleep(interval_sec) except KeyboardInterrupt: print(\n\n日志记录被用户中断。) except Exception as e: print(f\n记录过程中出错: {e}) finally: try: pynvml.nvmlShutdown() except: pass print(f监控结束。日志已保存至: {log_file}) if __name__ __main__: # 开始记录每5秒一次 monitor_and_log_gpu(log_filegpu_usage_log.csv, interval_sec5)运行这个脚本后你会得到一个CSV文件。用Excel或任何文本编辑器打开就能看到按时间排列的所有监控数据。你可以用这些数据绘制图表分析在运行Qwen模型进行长文本生成时显存占用是如何逐步上升的或者GPU利用率在哪些时刻达到了峰值。4. 监控脚本与Qwen模型结合使用现在我们有了监控工具怎么把它和实际的Qwen1.5-1.8B GPTQ模型运行结合起来呢这里有几个实用的思路。4.1 在另一个终端并行运行最简单的方法就是打开两个终端窗口。第一个终端正常启动你的Qwen模型推理脚本。第二个终端运行我们上面写的monitor_and_log_gpu.py脚本。这样你就能在不干扰主程序的情况下实时观察资源消耗。特别是在模型加载、第一次推理预热以及处理超长输入时观察资源曲线的变化非常直观。4.2 将监控集成到模型脚本中进阶如果你希望监控更紧密地结合比如只在模型推理期间监控或者根据监控结果动态调整批次大小可以将监控代码封装成函数嵌入到你的主脚本里。下面是一个高度简化的示例展示这个思路# 你的Qwen模型推理脚本的一部分 (例如inference_with_monitor.py) import torch from transformers import AutoModelForCausalLM, AutoTokenizer import pynvml import time import threading # ---- 监控线程函数 ---- def monitor_thread(interval1, stop_eventNone): 在后台线程中运行监控 pynvml.nvmlInit() handle pynvml.nvmlDeviceGetHandleByIndex(0) # 假设只有一块GPU print(开始后台GPU监控...) while not stop_event.is_set(): mem_info pynvml.nvmlDeviceGetMemoryInfo(handle) used_gb mem_info.used / 1024**3 util pynvml.nvmlDeviceGetUtilizationRates(handle).gpu print(f[Monitor] 显存: {used_gb:.2f} GB, 利用率: {util}%) time.sleep(interval) pynvml.nvmlShutdown() print(后台监控停止。) # ---- 主推理逻辑 ---- def main(): device cuda if torch.cuda.is_available() else cpu print(f使用设备: {device}) # 1. 启动监控线程 stop_monitor threading.Event() monitor threading.Thread(targetmonitor_thread, args(2, stop_monitor)) monitor.start() time.sleep(1) # 给监控线程一点启动时间 try: # 2. 加载模型和分词器 (这里需要你替换成实际的Qwen GPTQ加载方式) print(正在加载模型...) # model_name Qwen/Qwen1.5-1.8B-GPTQ-Int4 # 示例模型名 # tokenizer AutoTokenizer.from_pretrained(model_name) # model AutoModelForCausalLM.from_pretrained(model_name, device_mapauto) # 请根据你的实际模型加载方式修改以上代码 # 模拟一个耗时的推理过程 print(开始模拟推理任务...) for i in range(5): print(f\n--- 推理批次 {i1} ---) # 这里应该是你的实际推理代码 # inputs tokenizer(Hello, how are you?, return_tensorspt).to(device) # outputs model.generate(**inputs, max_new_tokens50) time.sleep(3) # 模拟推理耗时 print(\n推理任务完成。) finally: # 3. 停止监控线程 stop_monitor.set() monitor.join() if __name__ __main__: main()这个例子展示了如何在一个独立的线程中运行监控这样它就不会阻塞你的主推理流程。你可以看到在模型加载和每个推理批次前后GPU资源的使用情况。5. 解读监控数据它告诉了我们什么拿到数据后怎么分析呢这里有一些针对运行类似Qwen这样的语言模型的常见观察点显存占用Memory Used模型加载后会有一个基础的显存占用这是模型权重和初始缓存所占据的空间。Qwen1.5-1.8B GPTQ-Int4模型本身大约占用1.1-1.3GB显存。推理过程中显存会随着处理序列长度你的输入模型生成的增加而上升因为需要存储键值KV缓存。如果看到显存占用持续快速增长可能需要检查是否输入过长或生成了太多内容。峰值显存留意整个过程中的最高显存使用量确保它没有超过GPU的总显存否则会导致CUDA out of memory错误。GPU利用率GPU Utilization这个百分比反映了GPU计算核心的忙碌程度。在生成token推理时利用率通常会升高特别是使用优化过的内核时。如果利用率持续很低例如长期低于20%而你又感觉推理速度慢那瓶颈可能不在GPU计算上而是在数据准备、CPU处理或IO上。如果利用率持续接近100%说明GPU计算资源被充分利用此时推理速度主要受GPU算力限制。温度Temperature长时间高负载运行GPU温度会升高。大多数消费级GPU的安全工作温度在80-85°C以下。如果温度持续过高可能会触发降频保护导致性能下降。良好的机箱风道有助于保持低温。功耗Power Usage功耗直接反映了GPU的能耗水平也与温度和性能相关。在轻负载和满负载下功耗差异会很大。监控功耗可以帮助你估算运行模型的电费成本。通过长期记录这些数据你可以为自己的工作负载建立一份“资源画像”从而更好地规划硬件升级或者优化模型部署参数如批次大小、最大生成长度等。写这个监控脚本的过程其实也是理解GPU如何工作的过程。它从黑盒变成了一个你可以观察和测量的对象。实际用起来你会发现很多时候程序出问题并不是模型代码有bug而是资源不知不觉用超了。有了这个实时仪表盘你就能更快地定位到是显存不足、算力瓶颈还是散热问题。脚本虽然简单但非常实用。你可以根据自己的需求扩展它比如增加报警功能当显存超过90%时发个通知或者做一个简单的Web界面来展示仪表盘。最重要的是它让你在运行像Qwen这样的大模型时心里更有底。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。