nickprotop/cxgpu
GitHub: nickprotop/cxgpu
一个基于 .NET 的终端 GPU 监控工具,支持 NVIDIA 和 AMD 双厂商,提供实时仪表盘、进程管理、降频检测和 Prometheus 导出功能。
Stars: 5 | Forks: 0
# cxgpu
[](LICENSE)
[](https://dotnet.microsoft.com/)
[]()
[]()
**一个适用于终端的多厂商 GPU 监控工具,基于 [SharpConsoleUI](https://github.com/nickprotop/ConsoleEx) 构建。**
## 快速开始
**选项 1:一行命令安装**(Linux,无需 .NET)
```
curl -fsSL https://raw.githubusercontent.com/nickprotop/cxgpu/main/install.sh | bash
cxgpu
```
**Windows** (PowerShell)
```
irm https://raw.githubusercontent.com/nickprotop/cxgpu/main/install.ps1 | iex
```
**选项 2:从源码构建**(需要 .NET 10)
```
git clone https://github.com/nickprotop/cxgpu.git
cd cxgpu
./build-and-install.sh
cxgpu
```
手头没有 GPU?`cxgpu --demo` 会针对模拟的 GPU 运行——这对于在单 GPU 机器上体验多 GPU
视图,或者在没有 GPU 驱动程序的情况下尝试非常有用。
## 支持的硬件
cxgpu 会在启动时探测每个厂商,并显示它找到的所有设备——包括在混合架构机器上同时找到
两种设备。不存在的厂商直接不显示;不会出现任何报错。
| 厂商 | 数据源 | 平台 |
|---|---|---|
| **NVIDIA** | `nvidia-smi` | Linux, Windows |
| **AMD** | `sysfs` + `hwmon` + `/proc/*/fdinfo` | Linux |
| **AMD** | `amd-smi` / `rocm-smi` | Windows,或没有 sysfs 的 Linux |
Linux 上的 AMD 后端**不需要额外的工具,也不需要 root 权限**——它直接读取内核数据,
这不仅比 CLI 更快,而且是唯一能够将内存使用归因于各个进程的数据源。
## 视图
### 概览 — 深入了解单个 GPU
仪表盘加上用于利用率、内存、温度、功耗和风扇的盲文火花线历史记录,一行关键指标摘要,
编码/解码读数,以及设备的规格表:驱动程序、PCIe 链路、CUDA 版本、时钟频率、VRAM、
限制、VBIOS,以及当前正在使用的数据源。
**降频标记**仅在 GPU 真正处于降频状态时出现(`⚠ thermal`、`⚠ power cap`、
`⚠ hw slowdown`)——每张显卡都会报告的良性“空闲”状态位已被过滤掉,因此当你看到这个
标记时,它必定代表着实际情况。
### 仪表板 — 宏观掌控整个集群
在多 GPU 机器上,摘要栏会出现一个 **`‹DASH›` 标记**。选中它,概览界面就会变成集群视图:
左侧显示聚合总量(合并的 VRAM、总功耗、最热的显卡、总进程数、任何降频状态),右侧则显示
每个 GPU 的主要面板。双击某个面板即可直接跳转到该 GPU 的详细视图。

### 进程 — 谁在使用 GPU
一个可展开的 GPU 进程树,带有工具栏可按 GPU 进行过滤(或同时显示**所有 GPU**),并支持
按内存、SM%、PID 或名称排序。展开某行可查看完整的命令路径和实时的进程详细数据;在此处
你可以发送 **SIGTERM** 或 **SIGKILL** 信号,后者会要求确认。

操作结果会如实反馈:“权限被拒绝 — 属于另一个用户”和“已经退出”是截然不同的提示信息,
而不是笼统的失败报告。
## 功能
| | |
|---|---|
| 🖥️ **多厂商支持** | 在同一个视图中支持 NVIDIA 和 AMD,各自通过独立的后端运行 |
| 📊 **概览** | 带有盲文火花线历史记录的实时仪表盘、关键指标行,以及完整的设备规格表 |
| 🧩 **集群仪表板** | 通过 `‹DASH›` 标记提供每个 GPU 的主要面板及聚合总量 |
| 📋 **进程** | 可展开的树状结构,支持 GPU 过滤、排序、进程引擎使用率查看以及信号操作 |
| ⚠️ **降频检测** | 仅在发生真实降频时显示具体的降频原因 |
| 🔔 **警报** | 阈值与降频事件提示,包含 toast 通知、状态栏徽章以及历史记录浮窗 |
| 📈 **会话统计** | 每个 GPU 的峰值温度、峰值功耗及降频时间,支持在应用内及退出时显示 |
| 📡 **Prometheus** | `--prometheus` 提供 `/metrics` 端点;`--no-ui` 以无界面模式运行 |
| 🎬 **编码 / 解码** | 在硬件支持的情况下显示 NVENC/NVDEC 利用率 |
| 🎯 **能力感知** | 省略不支持的指标,绝不伪装成零 |
| 🎛️ **设置** | 分页设置对话框 (F9) — 包含刷新、图表、标签页、警报以及各后端选项 |
| ❓ **帮助浮层** | `?` 或 F1 列出所有快捷键,并标记出当前机器上不适用的项目 |
| 📐 **自适应** | 根据终端宽度自动调整 — 支持并排或堆叠,自动换行的面板网格 |
| 🧪 **演示模式** | `--demo[=N]` 可模拟最多 9 个 GPU,展现真实硬件无法按需生成的状态 |
## 键盘快捷键
| 按键 | 操作 |
|-----|--------|
| F2 / F3 | 概览 / 进程标签页 |
| `[` `]` | 上一个 / 下一个 GPU 磁贴(多 GPU) |
| 1–9 | 直接选择某个 GPU(多 GPU) |
| → / Enter | 展开进程行(进程视图) |
| ← | 折叠 |
| `k` | 向选中的进程发送信号(进程视图) |
| ? / F1 | 键盘快捷键 |
| F9 | 设置 |
| F10 / Esc | 退出 |
状态栏上的提示和 GPU 磁贴均可点击;双击仪表板上的面板即可打开对应的 GPU。
状态栏右侧的警报徽章可打开事件历史记录。
## 命令行
```
cxgpu [options]
--demo[=N] Run against N simulated GPUs (default 4, max 9) instead of
real hardware. Also settable via CXGPU_FAKE_GPUS=N.
--prometheus Serve Prometheus metrics at /metrics.
--port PORT Port for the exporter (default 9835).
--bind ADDRESS Interface to bind (default localhost). Use 0.0.0.0 for all.
--no-ui Run the exporter without the TUI. Requires --prometheus.
-h, --help Show help and exit.
-v, --version Show the version and exit.
```
## 警报
当 GPU 超过阈值,或者驱动程序本身报告降频时,cxgpu 就会触发一个事件。两者都会汇集到同
一个列表中,因此屏幕上的标记和警报历史记录绝不会出现不一致的情况。
- **警告**会弹出一个会自动消失的 toast 通知;**严重警报**弹出的通知则会一直保留,直到你
手动关闭。每个 GPU 的每个指标最多只会有一个 toast 通知,因此在阈值附近频繁波动的显卡
不会导致屏幕被大量通知淹没。
- 只要触发过任何警报,状态栏右侧就会出现一个**徽章**。点击它可查看历史记录 — 进行中的
事件会以彩色显示,已解决的事件会变暗并显示其持续时间。保留这些记录的意义在于:当条件
解除后,降频标记就会消失,否则像“我去吃午饭的时候它降频了吗?”这样的问题将无从知晓。
- 事件采用**带有迟滞机制的边缘触发**:每次状态变化只生成一个条目,而不是每次刷新都生成,
停在阈值边缘的数值也不会反复触发。
阈值按厂商划分,可在 **F9 → 警报**下进行编辑。默认值因部件而异,因为硬件本身就有差异 —
GeForce 在 83 °C 时发出警告,而 Radeon 在 90 °C 时发出警告。界面中所有地方的温度配色
都遵循相同的标准,因此你看到的颜色与实际触发的警报永远是一致的。
降频事件来源于驱动程序自身的原因标志位,绝非推断得出。如果某个后端无法读取这些标志位,
它将保持沉默,而不会错误地报告“未降频”。
## Prometheus
```
cxgpu --prometheus --no-ui & # headless exporter
cxgpu --prometheus # alongside the UI
cxgpu --prometheus --port 9100 --bind 0.0.0.0 # on every interface
```
指标通过 `/metrics` 端点提供服务,并与 UI 使用的数据提供程序读取相同的数据源,因此抓取到
的数据与屏幕上显示的数据绝不会有偏差。数据序列携带稳定的 `card` 标签(PCI 地址),以及
`gpu`、`name` 和 `backend` 标签 — 仅带有索引标签的数据序列在后端探测失败时,会隐式地指向
不同的硬件,这在 UI 中是不可见的,但在时序数据库中却是永久性的改变。
```
cxgpu_temperature_celsius{gpu="0",name="NVIDIA GeForce RTX 3090",backend="NVIDIA",card="0000:01:00.0"} 44
cxgpu_throttled{gpu="0",...,reason="thermal"} 0
```
**不支持的指标会被省略,而不是显示为零。** 在一台配置混合的机器上,NVIDIA 显卡会导出
风扇、功耗和降频数据序列,而 AMD 显卡则不会,因为该后端确实无法读取这些信息 — 一个伪造
的零值会被永久地平均计算到仪表板中,而没有任何人能察觉。
除非使用 `--bind` 另行指定,否则导出器默认绑定到 **localhost**。如果监听在公共网络,它会
在启动时发出警告;并且如果指定的端口已被占用,它会直接报错,而不是悄悄地选择另一个端口。
## 配置
设置以 JSON 文件形式保存在平台的配置文件路径中:
- **Linux:** `~/.config/cxgpu/config.json` (遵循 `XDG_CONFIG_HOME` 环境变量)
- **Windows:** `%APPDATA%\cxgpu\config.json`
你可以通过 **F9** 在应用内直接编辑它们。该对话框是分页的:包含刷新间隔、图表选项、标签页
可见性,以及针对每个 GPU 后端的专属页面(你可以在那里启用或禁用特定厂商,并修改其选项 —
例如,选择 AMD 后端读取数据的机制)。被禁用的后端完全不会被探测。
如果文件缺失或无效,系统会回退到默认值,从而保证应用始终能够启动。保存时会保留无法识别的
键,因此由更新版本生成的配置在降级使用时依然能够兼容。
## 架构
GPU 访问被统一封装在一个接口层之后。每个厂商对应一个**后端**,用于声明自身的能力和设置,
因此添加新厂商完全不需要改动 UI。
```
cxgpu/
├── Program.cs # Entry point, CLI parsing
├── Configuration/ # CxgpuConfig (JSON load/save)
├── Gpu/
│ ├── Abstractions/ # Models, IGpuBackend, capabilities, identity, fleet summary
│ ├── Alerts/ # Threshold engine, events, session stats
│ ├── GpuBackendRegistry.cs # Probes backends, aggregates, assigns global GPU indices
│ ├── GpuBackendPlugin.cs # Backends as SharpConsoleUI plugin services
│ ├── GpuStatsFactory.cs # Backend selection and configuration
│ ├── ProcessSignals.cs # SIGTERM/SIGKILL delivery
│ └── Backends/
│ ├── Nvidia/ # nvidia-smi
│ ├── Amd/ # sysfs + hwmon + fdinfo, or amd-smi/rocm-smi
│ └── Demo/ # Synthetic GPUs for --demo
├── Export/ # Prometheus formatter, HTTP exporter, CLI options
├── Dashboard/ # Main window, settings, help, busy indicator
├── Helpers/ # UI constants, shared metric formatting, history
├── Widgets/ # Reusable controls (hero panel, strip, alert portal)
└── Tabs/ # Overview (+ fleet dashboard), Processes
```
添加一个新厂商只需要编写一个后端即可 — UI、警报和导出器都会自动适应它所声明支持的读取
能力。详情请参阅 **[编写 GPU 后端](docs/WRITING-A-BACKEND.md)**。
各个后端均实现了 SharpConsoleUI 的 `IPluginService` 接口,因此它们已经是合法的插件 — 未来
该框架一旦支持运行时动态加载程序集,它们无需重构即可直接作为插件被载入。
## 从源码构建
cxgpu 对 [SharpConsoleUI](https://github.com/nickprotop/ConsoleEx) 采用了条件性的项目引用:
- **本地开发:** 如果 ConsoleEx 作为同级目录被克隆(`../ConsoleEx`),则会自动使用项目
引用。
- **CI/Release 构建:** 回退至使用 SharpConsoleUI NuGet 包。
```
# 将两个 repo 作为同级目录进行 Clone
git clone https://github.com/nickprotop/ConsoleEx.git
git clone https://github.com/nickprotop/cxgpu.git
cd cxgpu
dotnet build cxgpu.csproj
```
**核心技术:** .NET 10, [SharpConsoleUI](https://github.com/nickprotop/ConsoleEx), `nvidia-smi`,
Linux `sysfs`/`hwmon`, `amd-smi`/`rocm-smi`
## 卸载
**Linux:**
```
cxgpu-uninstall.sh
```
**Windows (PowerShell):**
```
& "$env:LOCALAPPDATA\cxgpu\cxgpu-uninstall.ps1"
```
## 贡献
欢迎提交 Bug 报告、硬件测试反馈和 Pull Request — 详见
[CONTRIBUTING.md](CONTRIBUTING.md)。添加新厂商只需实现一个独立的后端即可:
[编写 GPU 后端](docs/WRITING-A-BACKEND.md)。
## 许可证
MIT License。详情请参阅 [LICENSE](LICENSE)。
标签:GPU, 硬件信息, 自定义请求头