重置GPU.ps1
|
<#PSScriptInfo
.VERSION 1.1.0 .GUID 9c750cc4-ecc4-4f74-876c-4331a1c820ce .AUTHOR 埃博拉酱 .COMPANYNAME 无 .COPYRIGHT (c) 2026 埃博拉酱 .TAGS NVIDIA GPU Reset TDR PnP CUDA 显卡 重置 .LICENSEURI https://opensource.org/licenses/MIT #> <# .SYNOPSIS 重置指定序号的 NVIDIA GPU(无需重启整机);不指定参数时重置所有 GPU .DESCRIPTION 参考 https://juejin.cn/post/7663097122267414555 通过 Windows PnP 接口禁用再启用目标 GPU,触发驱动重新初始化, 清空 CUDA context、复位传感器、恢复时钟。 不带任何参数运行时,自动枚举 nvidia-smi 中所有 GPU 并逐个重置。 .PARAMETER 序号 GPU 在 nvidia-smi 中显示的序号(0, 1, 2, ...),可传多个,如 -序号 0,2。 省略时重置所有 GPU。 .EXAMPLE .\重置GPU.ps1 -序号 1 重置 GPU 1 .EXAMPLE .\重置GPU.ps1 重置所有 GPU .NOTES - 仅限未连接显示器的 GPU(Display Attached = No) - 重置会断开该 GPU 上所有 CUDA context,正在运行的计算任务将丢失 - 需要管理员权限运行 #> [CmdletBinding()] param( [Parameter(Mandatory = $false, Position = 0, HelpMessage = "GPU 序号(nvidia-smi 中的 index),可传多个;省略时重置所有 GPU")] [int[]]$序号 ) $ErrorActionPreference = 'Stop' # ========== 0. 检查管理员权限 ========== $当前用户 = [Security.Principal.WindowsIdentity]::GetCurrent() $主体 = New-Object Security.Principal.WindowsPrincipal($当前用户) if (-not $主体.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { Write-Error "请以管理员身份运行 PowerShell 后重试" exit 1 } # ========== 1. 确定要重置的 GPU 序号列表 ========== # 未指定任何参数时,枚举 nvidia-smi 中所有 GPU if (-not $序号) { Write-Host "==> 未指定序号,枚举所有 GPU..." -ForegroundColor Cyan $序号 = @(nvidia-smi --query-gpu=index --format=csv,noheader | ForEach-Object { [int]$_.Trim() }) if (-not $序号) { Write-Error "nvidia-smi 未检测到任何 GPU" exit 1 } Write-Host " 共发现 $($序号.Count) 个 GPU: $($序号 -join ', ')" } # ========== 2. 重置单个 GPU 的核心逻辑 ========== function Reset-SingleGpu { param([int]$Gpu序号) # --- 2.1 获取目标 GPU 的 PCI 总线号 --- Write-Host "`n==> 查询 GPU $Gpu序号 的 PCI 总线号..." -ForegroundColor Cyan $所有行 = nvidia-smi --query-gpu=index,pci.bus_id --format=csv,noheader $目标行 = $所有行 | Where-Object { [int](($_ -split ',')[0].Trim()) -eq $Gpu序号 } if (-not $目标行) { Write-Error "未找到序号为 $Gpu序号 的 GPU,请检查 nvidia-smi 输出" return } # bus_id 形如 00000000:36:00.0,取中间段十六进制转十进制 $总线号十六进制 = (($目标行 -split ',')[1].Trim() -split ':')[1] $总线号 = [Convert]::ToInt32($总线号十六进制, 16) Write-Host " PCI 总线号: 0x$总线号十六进制 = $总线号 (十进制)" # --- 2.2 确认 GPU 未连接显示器 --- Write-Host "==> 检查显示器连接状态..." -ForegroundColor Cyan $显示状态 = nvidia-smi -q -i $Gpu序号 | Select-String -Pattern 'Display Attached|Display Active' $已连接显示器 = ($显示状态 -match 'Display Attached\s+:\s+Yes') if ($已连接显示器) { Write-Warning "GPU $Gpu序号 连接了显示器,禁用会导致黑屏,已跳过" return } Write-Host " Display Attached: No (可安全重置)" # --- 2.3 通过 PCI 总线号匹配 PnP InstanceId --- Write-Host "==> 匹配 PnP InstanceId..." -ForegroundColor Cyan $显示设备 = Get-PnpDevice -Class 'Display' -Status OK, Unknown | Where-Object { $_.FriendlyName -like '*NVIDIA*' } $实例ID = $null foreach ($设备 in $显示设备) { $位置信息 = Get-PnpDeviceProperty -InstanceId $设备.InstanceId ` -KeyName 'DEVPKEY_Device_LocationInfo' -ErrorAction SilentlyContinue # 位置信息形如 "PCI bus 54, device 0, function 0" 或 "PCI 总线 54、设备 0、功能 0" if ($位置信息.Data -match "PCI (bus|总线)\s*$总线号[、,]") { $实例ID = $设备.InstanceId break } } if (-not $实例ID) { Write-Error "未找到 PCI 总线 $总线号 对应的 NVIDIA PnP 设备,已跳过 GPU $Gpu序号" return } Write-Host " InstanceId: $实例ID" # --- 2.4 显示重置前状态 --- Write-Host "`n===== GPU $Gpu序号 重置前状态 =====" -ForegroundColor Yellow nvidia-smi --query-gpu=index,utilization.gpu,power.draw,temperature.gpu,pstate,memory.used ` --format=csv -i $Gpu序号 # --- 2.5 禁用 → 等待 → 启用 --- Write-Host "`n==> 正在禁用 GPU $Gpu序号 ..." -ForegroundColor Cyan Disable-PnpDevice -InstanceId $实例ID -Confirm:$false Write-Host "==> 等待 3 秒..." -ForegroundColor Cyan Start-Sleep -Seconds 3 Write-Host "==> 正在重新启用 GPU $Gpu序号 ..." -ForegroundColor Cyan Enable-PnpDevice -InstanceId $实例ID -Confirm:$false # 等待驱动初始化完成 Start-Sleep -Seconds 2 # --- 2.6 验证重置结果 --- Write-Host "`n===== GPU $Gpu序号 重置后状态 =====" -ForegroundColor Green nvidia-smi --query-gpu=index,utilization.gpu,power.draw,temperature.gpu,pstate,memory.used ` --format=csv -i $Gpu序号 Write-Host "`nGPU $Gpu序号 重置完成 ✓" -ForegroundColor Green } # ========== 3. 逐个重置目标 GPU ========== foreach ($单个序号 in $序号) { Reset-SingleGpu -Gpu序号 $单个序号 } Write-Host "`n全部完成(共处理 $($序号.Count) 个 GPU)" -ForegroundColor Green Write-Host "提示:若利用率/功耗/温度仍为异常组合,可能需要重启整机" -ForegroundColor DarkGray |