Local web dashboard for checking GPU usage across SSH hosts.
uv run uvicorn gpu_viewer.app:app --host 127.0.0.1 --port 8000Then open http://127.0.0.1:8000.
Copy the example config and edit it for your local SSH aliases:
cp config/servers.example.json config/servers.json{
"refreshIntervalSeconds": 10,
"servers": [
{
"name": "gpu-node-a",
"sshHost": "gpu-node-a",
"teams": ["CL"],
"allocationLabel": "A100 * 4",
"allocationSource": "Kakao AI scholar",
"allocationExpiresAt": "2027-02-28"
},
{
"name": "gpu-node-b",
"sshHost": "gpu-node-b",
"gpuAssignments": [
{ "team": "Video", "gpuIndexes": [0, 1], "label": "shared pair" },
{ "team": "Embodied AI", "gpuIndexes": [2, 3], "label": "shared pair" }
]
},
{ "name": "local-workstation", "kind": "local", "group": "workstation" }
]
}Each sshHost should be an alias available to the local ssh command.
Use "group": "workstation" for SSH hosts that should appear in the workstation section.
Use teams when every GPU on a server belongs to the same team, or gpuAssignments with gpuIndexes when only specific GPU indices belong to a team.
config/servers.json, config/notifications.json, and config/profiles.json are ignored by Git because they can contain private host aliases, GPU UUIDs, PIN hashes, session hashes, and Slack webhook URLs.
To start from notification defaults:
cp config/notifications.example.json config/notifications.jsonThe dashboard supports multiple browser-persistent profiles. Create a profile from the login dialog, add an optional profile photo, protect it with a four-digit numeric PIN, and the browser will keep the session in an HTTP-only cookie. Use the Photo button in the header to update the current profile photo later.
Favorites, Slack webhook settings, and alert rules are stored per profile in config/profiles.json. When the first profile is created, existing config/notifications.json settings are imported into that profile once.
uv run --group dev pytest