Linux下显卡测试工具和脚本分享
-
样本测试环境是Ubuntu24.04,显卡4090D 48G魔改卡,用到GPU-RUN,stress-ng等,工具大家不用关心,直接复制脚本给AI,比如DeepSeek或者Gemini,让它们改就行了。主要有简单的显卡压力测试,显存测试,,还有系统内存测试,这些对魔改卡,二手内存都挺有用的。当然,烤机还是建议大家使用3D Mark或者Fury Mark等专业工具。由于跑AI的服务器很多人只装了Linux,而且AI高负载运行本身的烈度就是烤机级别的,所以我个人认为搭配脚本,Nvidia-smi等工具也就差不多了。
下面这个是显存测试脚本,检查显存坏快,对非ECC显存的显卡而言很实用:
cat << 'EOF' > ~/ex/vram_heavy_test.py import torch import sys print(f"📦 正在启动英伟达大显存/魔改卡物理专项分块扫描...") if not torch.cuda.is_available(): print("❌ 没找到 GPU 驱动") sys.exit(1) device = torch.device("cuda:0") # 物理显存总量 total_mem = torch.cuda.get_device_properties(0).total_memory print(f"⚡ 物理检测到总显存: {total_mem / (1024**3):.2f} GB") # 留出 2GB 驱动余量,其余全部压榨 usable_mem = total_mem - 2 * 1024 * 1024 * 1024 # 分块测试:每块分配 8GB chunk_size_bytes = 8 * 1024 * 1024 * 1024 num_chunks = int(usable_mem // chunk_size_bytes) element_per_chunk = int(chunk_size_bytes // 4) # int32 占 4 字节 print(f"🔥 自动开启分块轰炸模式:共分 {num_chunks} 块,每块 {chunk_size_bytes / (1024**3):.1f} GB 滚动压榨...") try: holder = [] # 模式一:分块写入全 0 并校验物理放电 print("\n -> [步骤 1/4] 分块写入全 0000 模式并校验物理放电...") for i in range(num_chunks): chunk = torch.zeros(element_per_chunk, dtype=torch.int32, device=device) torch.cuda.synchronize() if not (chunk == 0).all().item(): raise ValueError(f"第 {i+1} 块显存放电校验失败!") holder.append(chunk) print(f" [OK] 成功霸占并校验 {len(holder) * 8} GB 显存全 0 写入。") # 释放并清理 del holder; torch.cuda.empty_cache(); holder = [] # 模式二:分块写入全 1 并校验物理充电 print("\n -> [步骤 2/4] 分块写入全 1111 模式并校验物理充电...") for i in range(num_chunks): chunk = torch.full((element_per_chunk,), -1, dtype=torch.int32, device=device) torch.cuda.synchronize() if not (chunk == -1).all().item(): raise ValueError(f"第 {i+1} 块显存充电校验失败!") holder.append(chunk) print(f" [OK] 成功霸占并校验 {len(holder) * 8} GB 显存全 1 写入。") # 释放并清理 del holder; torch.cuda.empty_cache(); holder = [] # 模式三 & 四:棋盘格交替位元高频冲刷与深度校验 print("\n -> [步骤 3/4] 发起物理交替位元高频冲刷 (0101 棋盘格)...") # 【核心修正】直接利用有符号整型溢出特性得到对应的 int32 标量 # 0x55555555 -> 1431655765 # 0xAAAAAAAA -> -1431655766 p1 = 1431655765 p2 = -1431655766 for i in range(num_chunks): chunk = torch.empty(element_per_chunk, dtype=torch.int32, device=device) # 使用原生 int32 标量通过 fill_ 填充,完美避开 Python 自带的边界拦截 chunk[0::2].fill_(p1) chunk[1::2].fill_(p2) holder.append(chunk) torch.cuda.synchronize() print(f" [OK] 成功写入并高频冲刷棋盘格位元模式。") print("\n -> [步骤 4/4] 正在进行全量显存深度读取校验...") for i, chunk in enumerate(holder): if not (chunk[0::2] == p1).all().item(): raise ValueError(f"第 {i+1} 块奇数位元干扰校验失败!") if not (chunk[1::2] == p2).all().item(): raise ValueError(f"第 {i+1} 块偶数位元干扰校验失败!") print(f"\n🎉【显存物理体检通过】这块 {total_mem / (1024**3):.1f}GB 的大显存卡通过 100% 逐位读写测试!") except Exception as e: print(f"\n❌【显存检测失败】: {e}") sys.exit(1) EOF # 再次启动! python ~/ex/vram_heavy_test.pyGPU- RUN压力测试:
# 1. 强行激活虚拟环境(确保在 venv 状态下) source /mnt/nvidia/venv_4090/bin/activate # 2. 直接一行命令写出一个暴力硬件压力测试脚本 cat << 'EOF' > ~/ex/gpu_hardware_test.py import torch import time import sys print(f"📦 正在检测硬件设备: {torch.cuda.get_device_name(0)}") print(f"⚡ 当前 CUDA 版本: {torch.version.cuda}") # 强行拉起一个 20000x20000 的恐怖巨型浮点矩阵(直接把显存和计算核心撑爆) device = torch.device("cuda:0") try: print("🚀 正在往显存里疯狂塞入大量物理数据...") x = torch.randn(20000, 20000, dtype=torch.bfloat16, device=device) y = torch.randn(20000, 20000, dtype=torch.bfloat16, device=device) print("🔥 矩阵已就绪,正式发起 1000 轮全血满载高频计算轰炸(请盯紧系统状态)...") start_time = time.time() for i in range(1, 1001): # 连续进行极其高频的矩阵乘法冲刷 z = torch.matmul(x, y) # 每 100 轮强制进行一次物理同步和显存冲刷(专门去踩你之前的 Xid 158 断层) if i % 100 == 0: torch.cuda.synchronize() print(f" -> [进度] 已顶过 {i}/1000 轮高频轰炸...") torch.cuda.synchronize() print(f"🎉【测试通过】显卡硬件抗住了全部物理轰炸!耗时: {time.time() - start_time:.2f} 秒!") except Exception as e: print(f"\n❌ 软件层捕获到异常: {e}") sys.exit(1) EOF # 3. 直接开轰! python ~/ex/gpu_hardware_test.py系统内存检查:
sudo apt-get install -y stress-ng # 强行用 8 个线程,把 90% 的系统总内存全部塞满高频读写,测试 2 分钟 stress-ng --vm 8 --vm-bytes 90% --timeout 120s --metrics-brief -
谢谢老特,刚好我也需要到
现在先把nvlink 寄回给商家
从马来西亚寄回显卡困难重重摘要
组件 状态 备注 GPU 0 silicon (compute)
PASS1000 轮 20K×20K bf16 矩阵乘,100% util,70°C 峰值 GPU 1 silicon (compute)
PASS同上,68°C 峰值 GPU 0 VRAM
PASS12 GB 全位元扫描(0/1/0xAA/0x55)零错误 GPU 1 VRAM
PASS同上 Host RAM (62 GB)
PASSstress-ng 8 线程 × 90% × 120s 无错误 PCIe Gen 3 x16 (per GPU)
PASS负载下 Gen 3 x16,怠速 Gen 1(节能正常) NVLink link 0, 1, 2
PASS0 replay / 0 CRC during traffic NVLink link 3
FAIL物理硬件故障,单次测试累计 3,487 replay + 604 CRC
指标 GPU 0 GPU 1 100% util 持续时间 ~7 min ~7 min 峰值温度 70°C 68°C 峰值功耗 230 W 239 W 时钟频率 1425 MHz boost 1380 MHz boost 风扇 75% 41-68% 节流事件 无 无 CUDA error 无 无 退出 干净 干净 结论: 两张 3090 硅芯片在 sustained tensor-core 负载下完全稳定。无热降频、无功耗削顶、无 GPU 故障。
二、GPU 显存(VRAM)- 物理颗粒扫描
方法: 每张卡分配 12 GB scratch buffer,写入并验证 4 种位模式:
- 全 0x00000000(零电荷)
- 全 0x3f800000(fp32 1.0,约一半位为 1)
- 全 0xAAAAAAAA(棋盘 10101010...)
- 全 0x55555555(反棋盘 01010101...)
每次完整写入 + 全显存读取校验。
带宽实测: 12 GB 读写一轮 ~0.1-0.2s = 约 120 GB/s,与 3090 HBM 规格一致。
Pattern GPU 0 mismatches GPU 1 mismatches 0x00000000 0 0 fp32 1.0 0 0 0xAAAAAAAA 0 0 0x55555555 0 0 结论: 两张卡所有显存位完全正确。无虚焊、无颗粒坏点、无相邻位干扰。
说明:测试覆盖 12/24 GB(约一半),但所有 32 个位位置都被反复读写。系统性的位错误一定会在 12 GB 样本中暴露。
三、Host RAM - stress-ng 压力测试
方法:
stress-ng --vm 8 --vm-bytes 90% --timeout 120s --metrics-brief8 线程同时高频读写 ~56 GB(系统 62 GB 的 90%),持续 120 秒。
指标 数值 实际运行时长 120.50 秒 bogo ops 总数 18,358,645 bogo ops/秒(real time) 152,352 bogo ops/秒(usr+sys time) 19,151 失败 stressor 数 0 跳过 stressor 数 0 metrics 可信度 完全可信 结论: 62 GB ECC-less DDR4 主机内存完全健康,cross-NUMA 内存访问无错误。
-
谢谢锤哥的脚本,我让deepseek改了两稿才能正确的在windows下执行:【import torch
import sys
import os建议开启 expandable_segments 避免碎片(对 PyTorch 1.11+ 有效)
os.environ['PYTORCH_CUDA_ALLOC_CONF'] = 'expandable_segments:True'
print(f"
正在启动英伟达消费级显存物理专项扫描...")
if not torch.cuda.is_available():
print("
没找到 GPU 驱动")
sys.exit(1)device = torch.device("cuda:0")
获取总显存,多留一些空间给驱动和系统(这里留 3GB)
total_mem = torch.cuda.get_device_properties(0).total_memory
safe_margin = 3 * 1024 * 1024 * 1024 # 3 GB
usable_mem = total_mem - safe_margin
print(f"
物理检测到总显存: {total_mem / (10243):.2f} GB")
print(f"
预留安全边界后可用显存: {usable_mem / (10243):.2f} GB")分块大小:每次分配 2GB 的 float32 张量(即 512M 个元素),避免一次性大块失败
chunk_bytes = 2 * 1024 * 1024 * 1024
chunk_elements = chunk_bytes // 4 # float32 每个 4 字节
num_chunks = usable_mem // chunk_bytesprint(f"
采用分块扫描策略,共 {num_chunks} 块,每块 {chunk_bytes / (1024**3):.2f} GB")
print(f"
开始物理交替位元扫雷测试(耗时较长)...\n")try:
for chunk_idx in range(num_chunks):
print(f" -> [块 {chunk_idx+1}/{num_chunks}] 写入全 0 模式并校验物理放电...")
grid0 = torch.zeros(chunk_elements, dtype=torch.float32, device=device)
torch.cuda.synchronize()
if not (grid0 == 0).all():
raise ValueError(f"块 {chunk_idx+1} 放电校验失败!")
del grid0print(f" -> [块 {chunk_idx+1}/{num_chunks}] 写入全 1 模式并校验物理充电...") grid1 = torch.ones(chunk_elements, dtype=torch.float32, device=device) torch.cuda.synchronize() if not (grid1 == 1).all(): raise ValueError(f"块 {chunk_idx+1} 充电校验失败!") del grid1 print(f" -> [块 {chunk_idx+1}/{num_chunks}] 交替位元高频冲刷...") pattern = torch.arange(0, chunk_elements, dtype=torch.float32, device=device) torch.cuda.synchronize() # 简单校验:求和 s = pattern.sum().item() del pattern torch.cuda.empty_cache() # 每块完成后清理缓存 print(f" ✔ 块 {chunk_idx+1} 通过。\n") print(f"🎉【显存物理体检通过】所有魔改颗粒逐位读写 100% 正确!")except Exception as e:
print(f"\n
【铁证如山】显存物理颗粒扫描失败: {e}")
sys.exit(1)】我x99洋垃圾上的3090和3060都检测通过:【
D:\temp>python vram_heavy_test.py
正在启动英伟达消费级显存物理专项扫描...
物理检测到总显存: 12.00 GB
预留安全边界后可用显存: 11.00 GB
采用分块扫描策略,共 5 块,每块 2.00 GB
开始物理交替位元扫雷测试(耗时较长)...-> [块 1/5] 写入全 0 模式并校验物理放电...
D:\temp\vram_heavy_test.py:32: UserWarning: expandable_segments not supported on this platform (Triggered internally at C:\actions-runner_work\pytorch\pytorch\pytorch\c10/cuda/CUDAAllocatorConfig.h:28.)
grid0 = torch.zeros(chunk_elements, dtype=torch.float32, device=device)
-> [块 1/5] 写入全 1 模式并校验物理充电...
-> [块 1/5] 交替位元高频冲刷...
块 1 通过。-> [块 2/5] 写入全 0 模式并校验物理放电...
-> [块 2/5] 写入全 1 模式并校验物理充电...
-> [块 2/5] 交替位元高频冲刷...
块 2 通过。-> [块 3/5] 写入全 0 模式并校验物理放电...
-> [块 3/5] 写入全 1 模式并校验物理充电...
-> [块 3/5] 交替位元高频冲刷...
块 3 通过。-> [块 4/5] 写入全 0 模式并校验物理放电...
-> [块 4/5] 写入全 1 模式并校验物理充电...
-> [块 4/5] 交替位元高频冲刷...
块 4 通过。-> [块 5/5] 写入全 0 模式并校验物理放电...
-> [块 5/5] 写入全 1 模式并校验物理充电...
-> [块 5/5] 交替位元高频冲刷...
块 5 通过。
【显存物理体检通过】所有魔改颗粒逐位读写 100% 正确!D:\temp>python vram_heavy_test.py
正在启动英伟达消费级显存物理专项扫描...
物理检测到总显存: 23.99 GB
预留安全边界后可用显存: 20.99 GB
采用分块扫描策略,共 10 块,每块 2.00 GB
开始物理交替位元扫雷测试(耗时较长)...-> [块 1/10] 写入全 0 模式并校验物理放电...
D:\temp\vram_heavy_test.py:32: UserWarning: expandable_segments not supported on this platform (Triggered internally at C:\actions-runner_work\pytorch\pytorch\pytorch\c10/cuda/CUDAAllocatorConfig.h:28.)
grid0 = torch.zeros(chunk_elements, dtype=torch.float32, device=device)
-> [块 1/10] 写入全 1 模式并校验物理充电...
-> [块 1/10] 交替位元高频冲刷...
块 1 通过。-> [块 2/10] 写入全 0 模式并校验物理放电...
-> [块 2/10] 写入全 1 模式并校验物理充电...
-> [块 2/10] 交替位元高频冲刷...
块 2 通过。-> [块 3/10] 写入全 0 模式并校验物理放电...
-> [块 3/10] 写入全 1 模式并校验物理充电...
-> [块 3/10] 交替位元高频冲刷...
块 3 通过。-> [块 4/10] 写入全 0 模式并校验物理放电...
-> [块 4/10] 写入全 1 模式并校验物理充电...
-> [块 4/10] 交替位元高频冲刷...
块 4 通过。-> [块 5/10] 写入全 0 模式并校验物理放电...
-> [块 5/10] 写入全 1 模式并校验物理充电...
-> [块 5/10] 交替位元高频冲刷...
块 5 通过。-> [块 6/10] 写入全 0 模式并校验物理放电...
-> [块 6/10] 写入全 1 模式并校验物理充电...
-> [块 6/10] 交替位元高频冲刷...
块 6 通过。-> [块 7/10] 写入全 0 模式并校验物理放电...
-> [块 7/10] 写入全 1 模式并校验物理充电...
-> [块 7/10] 交替位元高频冲刷...
块 7 通过。-> [块 8/10] 写入全 0 模式并校验物理放电...
-> [块 8/10] 写入全 1 模式并校验物理充电...
-> [块 8/10] 交替位元高频冲刷...
块 8 通过。-> [块 9/10] 写入全 0 模式并校验物理放电...
-> [块 9/10] 写入全 1 模式并校验物理充电...
-> [块 9/10] 交替位元高频冲刷...
块 9 通过。-> [块 10/10] 写入全 0 模式并校验物理放电...
-> [块 10/10] 写入全 1 模式并校验物理充电...
-> [块 10/10] 交替位元高频冲刷...
块 10 通过。
【显存物理体检通过】所有魔改颗粒逐位读写 100% 正确!
】 -
为什么着急试用锤哥的脚本,因为我最近遇到了糟心的事情:
我的3060加载Qwen3-VL-8B-Instruct-Q4_K_M.gguf,只要识别图片100%的死机。还没有找到问题所在,我的工作中需要有一个模型能识别看图片......
@joker_chang 我也是因为高强度用的时候gpu 假死卡机 需要从启 所以才测测
-
@joker_chang 加载VL模型看图就死机,这个现象有几个可能的原因,我来帮你排查一下:
1. 先跑显存测试确认硬件没问题
你在用的就是锤哥的显存测试脚本对吧?先跑一轮完整的显存测试(建议跑2次),排除显存有坏块。3060 12G的显存如果之前跑过高负载训练或者矿过,出现坏块的概率是有的。2. Qwen3-VL-8B Q4_K_M的显存占用估算
- 模型本身 ≈ 5.5-6GB
- KV cache(默认8K上下文)≈ 0.5-1GB
- 图片编码(Vision Tower + 图像embedding)≈ 2-3GB
- 总计 ≈ 8-10GB
3060 12G理论够,但如果你同时跑了其他东西(浏览器、IDE等),或者系统的显存占用没清干净,就会刚好爆。
3. 最可能的原因——llama.cpp的mmproj加载问题
Qwen3-VL需要用--mmproj指定视觉投影文件(mmproj-Qwen_Qwen3.6-27B-f16.gguf 或对应的8B版)。如果你的启动参数里没有--mmproj,或者mmproj文件版本不匹配,llama.cpp在处理图片时会crash。建议的启动参数:
llama-server -m Qwen3-VL-8B-Q4_K_M.gguf \ --mmproj mmproj-Qwen_Qwen3-VL-8B-f16.gguf \ -ngl 99 \ --flash-attn \ -c 81924. 分批加载测试
先用纯文本模式(不加--mmproj)跑一下,确认模型本身能稳定运行。如果纯文本不崩溃,那就是视觉部分的问题。
然后不加图片,只发送纯文本请求给llama-server,确认能正常返回。如果这一步也有问题,考虑换驱动版本。5. 驱动版本
如果是Linux,建议NVIDIA驱动 550+ 版本。如果是Windows,确保CUDA 12.x runtime和驱动匹配。建议先走1→3→4的顺序排查,大概率是mmproj配置或显存瓶颈,不太可能是显卡坏了。
-
@joker_chang 我也是因为高强度用的时候gpu 假死卡机 需要从启 所以才测测
@applejuice 我换成【set MODEL_PATH=D:\MyModels\unsloth\gemma-4-12b-it-GGUF\gemma-4-12b-it-Q4_K_M.gguf
set MMProj_PATH=D:\MyModels\unsloth\gemma-4-12b-it-GGUF\mmproj-F32.gguf】,现在不死机了。但是这个模型有点傻,感觉不行
-
@applejuice 我换成【set MODEL_PATH=D:\MyModels\unsloth\gemma-4-12b-it-GGUF\gemma-4-12b-it-Q4_K_M.gguf
set MMProj_PATH=D:\MyModels\unsloth\gemma-4-12b-it-GGUF\mmproj-F32.gguf】,现在不死机了。但是这个模型有点傻,感觉不行
-
,
T terry 取消固定了此主题
-
我这个显卡还OK吧?
daniel@daniel-Default-string:~$ ~/ex/test_env/bin/python3 ~/ex/vram_heavy_test.py
正在启动英伟达显存物理专项扫描...
物理检测到总显存: 47.37 GB
正在对魔改颗粒下发物理交替位元扫雷测试...
-> [步骤1/4] 写入全0000模式并校验...
-> [步骤2/4] 写入全1111模式并校验...
-> [步骤3/4] 发起物理交替位元高频冲刷...
-> [步骤4/4] 正在进行全量显存深度读取校验...
【显存物理体检通过】所有魔改颗粒读写 100% 正确!
daniel@daniel-Default-string:~$ ~/ex/test_env/bin/python3 ~/ex/gpu_hardware_test.py
检测硬件设备: NVIDIA GeForce RTX 4090
当前 CUDA 版本: 13.0
载入巨型浮点矩阵...
矩阵已就绪,发起 1000 轮高频计算轰炸...
-> 已顶过 100/1000 轮轰炸...
-> 已顶过 200/1000 轮轰炸...
-> 已顶过 300/1000 轮轰炸...
-> 已顶过 400/1000 轮轰炸...
-> 已顶过 500/1000 轮轰炸...
-> 已顶过 600/1000 轮轰炸...
-> 已顶过 700/1000 轮轰炸...
-> 已顶过 800/1000 轮轰炸...
-> 已顶过 900/1000 轮轰炸...
-> 已顶过 1000/1000 轮轰炸...
【测试通过】耗时: 104.54 秒! -
我这个显卡还OK吧?
daniel@daniel-Default-string:~$ ~/ex/test_env/bin/python3 ~/ex/vram_heavy_test.py
正在启动英伟达显存物理专项扫描...
物理检测到总显存: 47.37 GB
正在对魔改颗粒下发物理交替位元扫雷测试...
-> [步骤1/4] 写入全0000模式并校验...
-> [步骤2/4] 写入全1111模式并校验...
-> [步骤3/4] 发起物理交替位元高频冲刷...
-> [步骤4/4] 正在进行全量显存深度读取校验...
【显存物理体检通过】所有魔改颗粒读写 100% 正确!
daniel@daniel-Default-string:~$ ~/ex/test_env/bin/python3 ~/ex/gpu_hardware_test.py
检测硬件设备: NVIDIA GeForce RTX 4090
当前 CUDA 版本: 13.0
载入巨型浮点矩阵...
矩阵已就绪,发起 1000 轮高频计算轰炸...
-> 已顶过 100/1000 轮轰炸...
-> 已顶过 200/1000 轮轰炸...
-> 已顶过 300/1000 轮轰炸...
-> 已顶过 400/1000 轮轰炸...
-> 已顶过 500/1000 轮轰炸...
-> 已顶过 600/1000 轮轰炸...
-> 已顶过 700/1000 轮轰炸...
-> 已顶过 800/1000 轮轰炸...
-> 已顶过 900/1000 轮轰炸...
-> 已顶过 1000/1000 轮轰炸...
【测试通过】耗时: 104.54 秒! -
这样算不算极限压力测试
text
100.0% proc'd: 29356 (53855 Gflop/s) errors: 0 temps: 79°C
...
GPU 0: OK
项目 数值 含义
100.0% proc'd 完成 测试跑完了全程,没有中途崩溃
29356 迭代次数 GPU 完成了近 3 万次矩阵运算,每次都会读写大量显存
53855 Gflop/s 算力 约 53.9 TFLOPS,对于 4090 来说属于正常满载水平
errors: 0 完美 没有任何计算错误,说明显存和核心都稳定
temps: 79°C 温度 4090 满载 79°C 非常健康(通常在 70-85°C 都算正常)
GPU 0: OK 最终结论 通过
-
正在启动英伟达大显存/魔改卡物理专项分块扫描...
物理检测到总显存: 31.35 GB
自动开启分块轰炸模式:共分 3 块,每块 8.0 GB 滚动压榨...-> [步骤 1/4] 分块写入全 0000 模式并校验物理放电... [OK] 成功霸占并校验 24 GB 显存全 0 写入。 -> [步骤 2/4] 分块写入全 1111 模式并校验物理充电... [OK] 成功霸占并校验 24 GB 显存全 1 写入。 -> [步骤 3/4] 发起物理交替位元高频冲刷 (0101 棋盘格)... [OK] 成功写入并高频冲刷棋盘格位元模式。 -> [步骤 4/4] 正在进行全量显存深度读取校验... 🎉【显存物理体检通过】这块 31.4GB 的大显存卡通过 100% 逐位读写测试! 两次测试汇总: | 测试 | 内容 | 结果 | |--------------|---------------------------------|-----------| | 显存物理体检 | 24GB 逐位读写(全0/全1/棋盘格) | ✅ 通过 | | GPU 计算轰炸 | 20000x20000 矩阵乘法 x1000 轮 | ✅ 71.6秒 | -
,
W williamlouis 引用了 此主题