本地网页,实时监控远程 SSH 主机上的 昇腾 NPU 占用情况。零构建、零数据库,开箱即用。
- 增 / 删 / 改 SSH 主机(支持密码和私钥两种认证)
- 一键开始 / 停止监控
- 每张卡片实时显示各 NPU 的 利用率 + HBM 内存
- 最近 5 分钟 利用率趋势曲线(Chart.js)
- 可选显示
npu-smi info原始输出,便于排查解析问题 - 配置保存在本地
data/hosts.json - SSH 反向代理:同步
~/.ssh/config中的*-proxy,也可在页面添加自定义隧道 - 代理隧道自动保活并在异常退出后退避重试,启动错误会保留在代理卡片中
启动后自动隐藏到系统托盘,终端立即返回(不挂起):
cd npus-usage
npm install
npm run tray
# → 终端立即返回,托盘继续在后台运行
# → 找系统托盘里的琥珀色方块图标完全无终端(双击启动):在文件资源管理器里双击 start-tray.vbs,连 cmd 窗口都不弹出。
弹出独立窗口(不再需要开浏览器),窗口内显示完整前端 UI。关闭窗口 = 隐藏到托盘,托盘 Quit 才彻底退出:
npm run app
# → 窗口自动弹出,显示 NPU Monitor UI
# → 关闭窗口后留在托盘;右键托盘 Quit 退出完全无终端(双击启动):双击 start-app.vbs。
托盘右键菜单:
- NPU Monitor · ● Running · :8787 (状态行,只读)
- Open Window —— 打开内置 Electron 窗口,显示同一套前端瀑布流和拖拽界面
- Start Backend / Stop Backend / Restart Backend —— 启停 HTTP 服务
- Quit —— 退出整个应用
托盘图标为琥珀色方块(tray-icon.png)。如需自定义图标,替换项目根的 tray-icon.png 后重启托盘应用。
cd npus-usage
npm install
npm start
# 或:node --watch server.js (热重载)浏览器打开 http://localhost:8787 ,点击右上角 添加主机。
| 字段 | 说明 | 默认 |
|---|---|---|
| 主机名 | 备注 | - |
| IP / 域名 | SSH 目标 | - |
| 端口 | SSH 端口 | 22 |
| 用户名 | SSH 用户 | - |
| 采集命令 | 在远端执行的命令 | npu-smi info |
| 刷新间隔 | 多久采一次 (ms) | 2000 |
| 认证 | 密码 / 私钥 | - |
| 显示原始输出 | 排查用 | 关 |
保存后点 测试 验证连通性,没问题就 开始 监控。
进入 PROXY 页面,可以直接启动 .ssh/config 中以 -proxy 结尾的 Host,也可以点击 ADD TUNNEL 填写机器地址、SSH 端口、本地服务端口、远端监听端口和用户名(默认 root)。自定义配置保存在 data/proxies.json。
自定义隧道使用 ssh -T -R <远端端口>:127.0.0.1:<本地端口> <用户>@<机器>,并运行带代理专属标记的远端保活命令。进程包含 SSH keepalive、连接超时和 ExitOnForwardFailure;异常退出后按指数退避自动重试,最多重试 6 次,手动停止会取消重试。如果远端端口被占用,程序会先检查本机是否存在命令行完全匹配的旧 SSH 隧道;本机未找到时,再通过独立 SSH 连接检查远端。只有目标端口由会话级 sshd: <user>@notty 持有,且其进程子树存在当前代理的专属标记时,才会向该会话 PID 发送 SIGTERM 并立即重连。不会停止 sshd 服务,也不会清理 VS Code、Terminal、Termius 或无标记的旧隧道会话。SSH 返回的失败原因和恢复状态会显示在隧道卡片下方。
默认执行 npu-smi info。如果你的版本输出格式不同,可在添加/编辑时把 采集命令 改为:
npu-smi info -t usages(部分固件支持)npu-smi info -t json(新版本支持)cat /proc/...等任意可输出 NPU 信息的命令
解析器目前内置对 npu-smi info 表格输出(带 Util / Memory-Usage(MiB) 列)的适配——会自动找列名、对齐取数。如果你的输出格式不同,勾选“显示原始输出” 可以直观看到原始文本,方便加新解析规则。
| Method | Path | 用途 |
|---|---|---|
GET |
/api/hosts |
列出所有主机(含运行状态) |
POST |
/api/hosts |
新增主机 |
PUT |
/api/hosts/:id |
更新主机(运行中会自动重启采集) |
DELETE |
/api/hosts/:id |
删除主机 |
POST |
/api/hosts/:id/start |
开始监控 |
POST |
/api/hosts/:id/stop |
停止监控 |
POST |
/api/hosts/:id/test |
跑 uname -a 测试连通性 |
GET |
/api/proxies |
列出 SSH config 与自定义隧道及运行状态 |
POST |
/api/proxies |
新增自定义反向代理隧道 |
DELETE |
/api/proxies/:id |
删除自定义隧道 |
POST |
/api/proxies/:id/start |
启动隧道并自动保活 |
POST |
/api/proxies/:id/stop |
停止隧道并取消重试 |
WS |
/ws |
实时推送(消息: subscribe / snapshot / sample / error) |
npus-usage/
├── server.js # Express + ssh2 + ws
├── package.json
├── public/
│ ├── index.html
│ ├── style.css
│ └── app.js
└── data/
├── hosts.json # 运行时生成,保存主机配置
└── proxies.json # 运行时生成,保存自定义代理配置
- 密码以明文保存在
data/hosts.json——这是本地工具,不建议在公网部署。若有需要可自行改用safeStorage/ 系统 keyring。 - 私钥路径只保存路径,文件本身不复制。
server.js每次连接时读取。 - SSH 连接会被复用(长连接 + 多次 exec),避免频繁握手开销。
- 端口可通过环境变量
PORT修改:PORT=9000 npm start。