keep-npu 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- keep_npu-1.0.1/LICENSE +21 -0
- keep_npu-1.0.1/MANIFEST.in +2 -0
- keep_npu-1.0.1/PKG-INFO +146 -0
- keep_npu-1.0.1/README.md +113 -0
- keep_npu-1.0.1/docs/compatibility.md +34 -0
- keep_npu-1.0.1/docs/releasing.md +31 -0
- keep_npu-1.0.1/docs/superpowers/plans/2026-07-21-keepgpu-parity.md +162 -0
- keep_npu-1.0.1/docs/superpowers/specs/2026-07-21-keepgpu-parity-design.md +238 -0
- keep_npu-1.0.1/docs/validation/ascend-remote-results.md +96 -0
- keep_npu-1.0.1/pyproject.toml +147 -0
- keep_npu-1.0.1/setup.cfg +4 -0
- keep_npu-1.0.1/src/keep_npu/__init__.py +4 -0
- keep_npu-1.0.1/src/keep_npu/cli.py +1722 -0
- keep_npu-1.0.1/src/keep_npu/global_npu_controller/__init__.py +4 -0
- keep_npu-1.0.1/src/keep_npu/global_npu_controller/global_npu_controller.py +132 -0
- keep_npu-1.0.1/src/keep_npu/legacy.py +239 -0
- keep_npu-1.0.1/src/keep_npu/mcp/__init__.py +0 -0
- keep_npu-1.0.1/src/keep_npu/mcp/server.py +1839 -0
- keep_npu-1.0.1/src/keep_npu/mcp/static/assets/dashboard.js +8 -0
- keep_npu-1.0.1/src/keep_npu/mcp/static/assets/index.css +1 -0
- keep_npu-1.0.1/src/keep_npu/mcp/static/index.html +13 -0
- keep_npu-1.0.1/src/keep_npu/single_npu_controller/__init__.py +6 -0
- keep_npu-1.0.1/src/keep_npu/single_npu_controller/ascend_npu_controller.py +226 -0
- keep_npu-1.0.1/src/keep_npu/single_npu_controller/base_npu_controller.py +23 -0
- keep_npu-1.0.1/src/keep_npu/utilities/__init__.py +3 -0
- keep_npu-1.0.1/src/keep_npu/utilities/endpoint_validation.py +71 -0
- keep_npu-1.0.1/src/keep_npu/utilities/humanized_input.py +134 -0
- keep_npu-1.0.1/src/keep_npu/utilities/json_protocol.py +25 -0
- keep_npu-1.0.1/src/keep_npu/utilities/logger.py +103 -0
- keep_npu-1.0.1/src/keep_npu/utilities/npu_info.py +158 -0
- keep_npu-1.0.1/src/keep_npu/utilities/npu_monitor.py +6 -0
- keep_npu-1.0.1/src/keep_npu/utilities/platform_manager.py +70 -0
- keep_npu-1.0.1/src/keep_npu/utilities/session_config.py +162 -0
- keep_npu-1.0.1/src/keep_npu.egg-info/PKG-INFO +146 -0
- keep_npu-1.0.1/src/keep_npu.egg-info/SOURCES.txt +37 -0
- keep_npu-1.0.1/src/keep_npu.egg-info/dependency_links.txt +1 -0
- keep_npu-1.0.1/src/keep_npu.egg-info/entry_points.txt +4 -0
- keep_npu-1.0.1/src/keep_npu.egg-info/requires.txt +14 -0
- keep_npu-1.0.1/src/keep_npu.egg-info/top_level.txt +1 -0
keep_npu-1.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Wang Siyuan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
keep_npu-1.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: keep-npu
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: KeepNPU is a polite NPU keeper with CLI, service, and MCP interfaces
|
|
5
|
+
Author: Peter Zheng
|
|
6
|
+
Maintainer: Peter Zheng
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: bugs, https://github.com/pzheng460/keep-npu/issues
|
|
9
|
+
Project-URL: changelog, https://github.com/pzheng460/keep-npu/releases
|
|
10
|
+
Project-URL: homepage, https://github.com/pzheng460/keep-npu
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Requires-Python: <3.14,>=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: typer
|
|
21
|
+
Requires-Dist: rich>=13.8.0
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: coverage; extra == "dev"
|
|
24
|
+
Requires-Dist: mypy; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest; extra == "dev"
|
|
26
|
+
Requires-Dist: ruff; extra == "dev"
|
|
27
|
+
Requires-Dist: black; extra == "dev"
|
|
28
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
29
|
+
Requires-Dist: bump-my-version; extra == "dev"
|
|
30
|
+
Requires-Dist: setuptools<82,>=77; extra == "dev"
|
|
31
|
+
Provides-Extra: ascend
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# KeepNPU
|
|
35
|
+
|
|
36
|
+
KeepNPU is a small, polite Huawei Ascend NPU keeper for shared machines. It
|
|
37
|
+
matches KeepGPU's CLI, service, REST/JSON-RPC, MCP, and dashboard workflows,
|
|
38
|
+
using `torch_npu` and `npu-smi` for Ascend devices.
|
|
39
|
+
|
|
40
|
+
It allocates only when utilization backoff permits, keeps the requested device
|
|
41
|
+
memory signal lightweight, and releases cleanly on exit.
|
|
42
|
+
|
|
43
|
+
## Requirements
|
|
44
|
+
|
|
45
|
+
- Python 3.9–3.13
|
|
46
|
+
- Huawei Ascend driver and CANN runtime
|
|
47
|
+
- A mutually compatible PyTorch and `torch_npu` installation
|
|
48
|
+
|
|
49
|
+
Load the CANN environment before using KeepNPU when your system does not do so
|
|
50
|
+
automatically:
|
|
51
|
+
|
|
52
|
+
```console
|
|
53
|
+
source /usr/local/Ascend/ascend-toolkit/latest/bin/setenv.bash
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Install
|
|
57
|
+
|
|
58
|
+
```console
|
|
59
|
+
python -m pip install keep-npu
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`torch` and `torch_npu` are deliberately not installed as package dependencies:
|
|
63
|
+
their versions must match the server's CANN and driver stack.
|
|
64
|
+
|
|
65
|
+
To install the latest unreleased revision directly from GitHub:
|
|
66
|
+
|
|
67
|
+
```console
|
|
68
|
+
python -m pip install 'keep-npu @ git+https://github.com/pzheng460/keep-npu.git'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Blocking mode
|
|
72
|
+
|
|
73
|
+
Keep all visible NPUs, or select torch-visible ordinals with `--npu-ids`:
|
|
74
|
+
|
|
75
|
+
```console
|
|
76
|
+
keep-npu --vram 1GiB --interval 60
|
|
77
|
+
keep-npu --npu-ids 0,2 --vram 512MiB --interval 30
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Press `Ctrl+C` to release memory. The default utilization threshold is 25%;
|
|
81
|
+
KeepNPU backs off while a device is busier than that or telemetry is unknown.
|
|
82
|
+
Use `--busy-threshold -1` only when you intentionally want to disable backoff.
|
|
83
|
+
|
|
84
|
+
## Service and dashboard
|
|
85
|
+
|
|
86
|
+
Run the local HTTP service in the foreground:
|
|
87
|
+
|
|
88
|
+
```console
|
|
89
|
+
keep-npu serve --host 127.0.0.1 --port 8765
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Open `http://127.0.0.1:8765/` for the dashboard. Non-blocking CLI workflows use
|
|
93
|
+
the same service and auto-start it on localhost by default:
|
|
94
|
+
|
|
95
|
+
```console
|
|
96
|
+
keep-npu list-npus
|
|
97
|
+
keep-npu start --npu-ids 0 --vram 1GiB --interval 60
|
|
98
|
+
keep-npu status
|
|
99
|
+
keep-npu stop --job-id JOB_ID
|
|
100
|
+
keep-npu stop --all
|
|
101
|
+
keep-npu service-stop
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The service exposes `GET /health`, `GET /api/npus`, and session CRUD under
|
|
105
|
+
`/api/sessions`. JSON-RPC is available at the exact `/rpc` endpoint, including
|
|
106
|
+
MCP-shaped `tools/list` and `tools/call` messages. As in KeepGPU 1.0, HTTP mode
|
|
107
|
+
is not a Streamable HTTP MCP endpoint; standards-based MCP transport is stdio.
|
|
108
|
+
|
|
109
|
+
## MCP server
|
|
110
|
+
|
|
111
|
+
For a local MCP client using stdio:
|
|
112
|
+
|
|
113
|
+
```console
|
|
114
|
+
keep-npu-mcp-server --mode stdio
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
For HTTP transport:
|
|
118
|
+
|
|
119
|
+
```console
|
|
120
|
+
keep-npu-mcp-server --mode http --host 127.0.0.1 --port 8765
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The MCP tools are `start_keep`, `stop_keep`, `status`, and `list_npus`.
|
|
124
|
+
|
|
125
|
+
## Ascend device semantics
|
|
126
|
+
|
|
127
|
+
`--npu-ids` always addresses the visible ordinal used by `torch.npu`, after
|
|
128
|
+
`ASCEND_RT_VISIBLE_DEVICES` filtering. `list-npus` additionally reports the
|
|
129
|
+
physical ID when it can be derived safely. Memory comes from `torch.npu` with
|
|
130
|
+
best-effort `npu-smi` telemetry; unavailable values are returned as `null`
|
|
131
|
+
instead of being guessed.
|
|
132
|
+
|
|
133
|
+
See [KeepGPU compatibility](https://github.com/pzheng460/keep-npu/blob/main/docs/compatibility.md)
|
|
134
|
+
for the exact public-name mapping and intentional Ascend differences.
|
|
135
|
+
|
|
136
|
+
## Development
|
|
137
|
+
|
|
138
|
+
```console
|
|
139
|
+
python -m pip install -e '.[dev]'
|
|
140
|
+
PYTHONPATH=src python -m pytest
|
|
141
|
+
cd web/dashboard && npm ci && npm test -- --run && npm run build
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Hardware tests use the `ascend` pytest marker and conservative memory sizes.
|
|
145
|
+
The original standalone `keep_npu_alive.py` entry point remains available for
|
|
146
|
+
backward compatibility.
|
keep_npu-1.0.1/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# KeepNPU
|
|
2
|
+
|
|
3
|
+
KeepNPU is a small, polite Huawei Ascend NPU keeper for shared machines. It
|
|
4
|
+
matches KeepGPU's CLI, service, REST/JSON-RPC, MCP, and dashboard workflows,
|
|
5
|
+
using `torch_npu` and `npu-smi` for Ascend devices.
|
|
6
|
+
|
|
7
|
+
It allocates only when utilization backoff permits, keeps the requested device
|
|
8
|
+
memory signal lightweight, and releases cleanly on exit.
|
|
9
|
+
|
|
10
|
+
## Requirements
|
|
11
|
+
|
|
12
|
+
- Python 3.9–3.13
|
|
13
|
+
- Huawei Ascend driver and CANN runtime
|
|
14
|
+
- A mutually compatible PyTorch and `torch_npu` installation
|
|
15
|
+
|
|
16
|
+
Load the CANN environment before using KeepNPU when your system does not do so
|
|
17
|
+
automatically:
|
|
18
|
+
|
|
19
|
+
```console
|
|
20
|
+
source /usr/local/Ascend/ascend-toolkit/latest/bin/setenv.bash
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```console
|
|
26
|
+
python -m pip install keep-npu
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`torch` and `torch_npu` are deliberately not installed as package dependencies:
|
|
30
|
+
their versions must match the server's CANN and driver stack.
|
|
31
|
+
|
|
32
|
+
To install the latest unreleased revision directly from GitHub:
|
|
33
|
+
|
|
34
|
+
```console
|
|
35
|
+
python -m pip install 'keep-npu @ git+https://github.com/pzheng460/keep-npu.git'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Blocking mode
|
|
39
|
+
|
|
40
|
+
Keep all visible NPUs, or select torch-visible ordinals with `--npu-ids`:
|
|
41
|
+
|
|
42
|
+
```console
|
|
43
|
+
keep-npu --vram 1GiB --interval 60
|
|
44
|
+
keep-npu --npu-ids 0,2 --vram 512MiB --interval 30
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Press `Ctrl+C` to release memory. The default utilization threshold is 25%;
|
|
48
|
+
KeepNPU backs off while a device is busier than that or telemetry is unknown.
|
|
49
|
+
Use `--busy-threshold -1` only when you intentionally want to disable backoff.
|
|
50
|
+
|
|
51
|
+
## Service and dashboard
|
|
52
|
+
|
|
53
|
+
Run the local HTTP service in the foreground:
|
|
54
|
+
|
|
55
|
+
```console
|
|
56
|
+
keep-npu serve --host 127.0.0.1 --port 8765
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Open `http://127.0.0.1:8765/` for the dashboard. Non-blocking CLI workflows use
|
|
60
|
+
the same service and auto-start it on localhost by default:
|
|
61
|
+
|
|
62
|
+
```console
|
|
63
|
+
keep-npu list-npus
|
|
64
|
+
keep-npu start --npu-ids 0 --vram 1GiB --interval 60
|
|
65
|
+
keep-npu status
|
|
66
|
+
keep-npu stop --job-id JOB_ID
|
|
67
|
+
keep-npu stop --all
|
|
68
|
+
keep-npu service-stop
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The service exposes `GET /health`, `GET /api/npus`, and session CRUD under
|
|
72
|
+
`/api/sessions`. JSON-RPC is available at the exact `/rpc` endpoint, including
|
|
73
|
+
MCP-shaped `tools/list` and `tools/call` messages. As in KeepGPU 1.0, HTTP mode
|
|
74
|
+
is not a Streamable HTTP MCP endpoint; standards-based MCP transport is stdio.
|
|
75
|
+
|
|
76
|
+
## MCP server
|
|
77
|
+
|
|
78
|
+
For a local MCP client using stdio:
|
|
79
|
+
|
|
80
|
+
```console
|
|
81
|
+
keep-npu-mcp-server --mode stdio
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
For HTTP transport:
|
|
85
|
+
|
|
86
|
+
```console
|
|
87
|
+
keep-npu-mcp-server --mode http --host 127.0.0.1 --port 8765
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The MCP tools are `start_keep`, `stop_keep`, `status`, and `list_npus`.
|
|
91
|
+
|
|
92
|
+
## Ascend device semantics
|
|
93
|
+
|
|
94
|
+
`--npu-ids` always addresses the visible ordinal used by `torch.npu`, after
|
|
95
|
+
`ASCEND_RT_VISIBLE_DEVICES` filtering. `list-npus` additionally reports the
|
|
96
|
+
physical ID when it can be derived safely. Memory comes from `torch.npu` with
|
|
97
|
+
best-effort `npu-smi` telemetry; unavailable values are returned as `null`
|
|
98
|
+
instead of being guessed.
|
|
99
|
+
|
|
100
|
+
See [KeepGPU compatibility](https://github.com/pzheng460/keep-npu/blob/main/docs/compatibility.md)
|
|
101
|
+
for the exact public-name mapping and intentional Ascend differences.
|
|
102
|
+
|
|
103
|
+
## Development
|
|
104
|
+
|
|
105
|
+
```console
|
|
106
|
+
python -m pip install -e '.[dev]'
|
|
107
|
+
PYTHONPATH=src python -m pytest
|
|
108
|
+
cd web/dashboard && npm ci && npm test -- --run && npm run build
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Hardware tests use the `ascend` pytest marker and conservative memory sizes.
|
|
112
|
+
The original standalone `keep_npu_alive.py` entry point remains available for
|
|
113
|
+
backward compatibility.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# KeepGPU compatibility
|
|
2
|
+
|
|
3
|
+
KeepNPU 1.0 follows KeepGPU 1.0's interaction model while translating the
|
|
4
|
+
device backend from CUDA/ROCm/MPS to Huawei Ascend.
|
|
5
|
+
|
|
6
|
+
| KeepGPU public contract | KeepNPU equivalent |
|
|
7
|
+
| --- | --- |
|
|
8
|
+
| `keep-gpu` | `keep-npu` |
|
|
9
|
+
| `keep-gpu-mcp-server` | `keep-npu-mcp-server` |
|
|
10
|
+
| `--gpu-ids` | `--npu-ids` |
|
|
11
|
+
| `list-gpus` / `/api/gpus` | `list-npus` / `/api/npus` |
|
|
12
|
+
| `gpu_ids` / `gpus` payload fields | `npu_ids` / `npus` |
|
|
13
|
+
| `~/.keepgpu` | `~/.keepnpu` |
|
|
14
|
+
| CUDA, ROCm, or MPS backend | Ascend `torch_npu` backend |
|
|
15
|
+
|
|
16
|
+
The blocking CLI, background service commands, job lifecycle, REST resources,
|
|
17
|
+
JSON-RPC methods, MCP tools, validation limits, dashboard flow, exit handling,
|
|
18
|
+
and utilization-backoff policy otherwise retain the KeepGPU behavior.
|
|
19
|
+
|
|
20
|
+
Intentional backend differences:
|
|
21
|
+
|
|
22
|
+
- `torch_npu` is imported lazily so help, validation, and service health remain
|
|
23
|
+
usable on a machine without the Ascend runtime.
|
|
24
|
+
- Device selectors are torch-visible ordinals. This avoids confusing a physical
|
|
25
|
+
card/chip ID with the post-filter ordinal accepted by `torch.npu.set_device`.
|
|
26
|
+
- `npu-smi` formats differ across Ascend products and driver versions. KeepNPU
|
|
27
|
+
treats telemetry as best effort and returns nullable metrics when a value
|
|
28
|
+
cannot be established safely.
|
|
29
|
+
- KeepNPU allocates float32 chunks and performs small in-place ReLU operations;
|
|
30
|
+
it does not assume CUDA-specific allocator or stream APIs. Ascend defaults to
|
|
31
|
+
one pass over the allocation per interval because KeepGPU's 5,000-pass GPU
|
|
32
|
+
default would generate roughly 10 TiB of memory traffic for a 1 GiB target.
|
|
33
|
+
- Hardware/vendor setup is not declared as a PyPI dependency because PyTorch,
|
|
34
|
+
`torch_npu`, CANN, and the driver must be installed as a compatible set.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Releasing KeepNPU
|
|
2
|
+
|
|
3
|
+
KeepNPU publishes the normalized distribution name `keep-npu`. A release
|
|
4
|
+
provides these commands after `python -m pip install keep-npu`:
|
|
5
|
+
|
|
6
|
+
- `keep-npu`
|
|
7
|
+
- `keep-npu-mcp-server`
|
|
8
|
+
- `keep-npu-alive`
|
|
9
|
+
|
|
10
|
+
## One-time PyPI setup
|
|
11
|
+
|
|
12
|
+
Configure a pending trusted publisher for the `keep-npu` project with:
|
|
13
|
+
|
|
14
|
+
- PyPI project name: `keep-npu`
|
|
15
|
+
- GitHub owner: `pzheng460`
|
|
16
|
+
- GitHub repository: `keep-npu`
|
|
17
|
+
- Workflow filename: `publish-pypi.yml`
|
|
18
|
+
- Environment name: `pypi`
|
|
19
|
+
|
|
20
|
+
No long-lived PyPI token is stored in GitHub. PyPI verifies the GitHub Actions
|
|
21
|
+
OIDC identity when the publish job runs.
|
|
22
|
+
|
|
23
|
+
## Publish a version
|
|
24
|
+
|
|
25
|
+
1. Update `__version__` and the matching `tool.bumpversion.current_version`.
|
|
26
|
+
2. Run the Python, dashboard, build, and installed-wheel checks.
|
|
27
|
+
3. Push the release commit and create a GitHub release tagged `vX.Y.Z`.
|
|
28
|
+
4. The release event builds a fresh sdist and wheel, then publishes both through
|
|
29
|
+
PyPI trusted publishing.
|
|
30
|
+
|
|
31
|
+
The workflow can also be started manually after the same tag/version checks.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# KeepGPU-Compatible KeepNPU Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Build an Ascend-native `keep-npu` package whose renamed public interfaces and lifecycle behavior match KeepGPU 1.0.0/current compatibility fixes, then validate it on configured SSH NPU hosts.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Port the tested KeepGPU package, service, dashboard, and test boundaries with a deterministic GPU-to-NPU naming map. Replace the platform-specific controllers and telemetry with one dependency-injected Ascend backend using `torch_npu` and `npu-smi`, while retaining the upstream validation, protocol, concurrency, and daemon-safety contracts.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Python 3.9–3.13, setuptools, Typer, Rich, PyTorch + torch_npu, stdlib HTTP/JSON-RPC, React/Vite/Vitest/Tailwind, pytest.
|
|
10
|
+
|
|
11
|
+
## Global Constraints
|
|
12
|
+
|
|
13
|
+
- Reference behavior is KeepGPU upstream commit `691720383f5325cffb9fc5960304541caec31444` and release 1.0.0.
|
|
14
|
+
- Public names use `keep-npu`, `keep-npu-mcp-server`, `--npu-ids`, `list-npus`, `npu_ids`, `npus`, and `~/.keepnpu`.
|
|
15
|
+
- Default service endpoint is `127.0.0.1:8765`.
|
|
16
|
+
- Unknown utilization is `null` and causes backoff unless `busy_threshold=-1`.
|
|
17
|
+
- Remote work uses unique temporary directories and leaves no daemon or workload behind.
|
|
18
|
+
- Production behavior is introduced only after a corresponding test has been observed failing.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
### Task 1: Port the public contract and package skeleton
|
|
23
|
+
|
|
24
|
+
**Files:**
|
|
25
|
+
- Create: `pyproject.toml`
|
|
26
|
+
- Create: `src/keep_npu/__init__.py`
|
|
27
|
+
- Create: `src/keep_npu/utilities/*.py`
|
|
28
|
+
- Create: `tests/utilities/*.py`
|
|
29
|
+
- Create: `tests/test_package_metadata.py`
|
|
30
|
+
- Modify: `.gitignore`
|
|
31
|
+
|
|
32
|
+
**Interfaces:**
|
|
33
|
+
- Produces: validators `validate_interval`, `validate_busy_threshold`, `validate_npu_ids`, `validate_job_id`; `parse_size`; strict JSON helpers; endpoint validators.
|
|
34
|
+
- Consumes: no project interfaces.
|
|
35
|
+
|
|
36
|
+
- [ ] Copy the upstream metadata and utility tests, mechanically map the approved public names, and run `pytest tests/utilities tests/test_package_metadata.py -q`; expect collection/import failure because `keep_npu` does not exist.
|
|
37
|
+
- [ ] Add the mapped package metadata and utility modules, keeping numeric, size, endpoint, session-id, and strict-JSON limits unchanged.
|
|
38
|
+
- [ ] Run `pytest tests/utilities tests/test_package_metadata.py -q`; expect all selected tests to pass.
|
|
39
|
+
- [ ] Run `python -m build`; expect wheel and source distribution creation with both console entry points declared.
|
|
40
|
+
- [ ] Commit with `feat: add KeepNPU package contracts`.
|
|
41
|
+
|
|
42
|
+
### Task 2: Implement Ascend discovery, telemetry, and controllers
|
|
43
|
+
|
|
44
|
+
**Files:**
|
|
45
|
+
- Create: `src/keep_npu/utilities/platform_manager.py`
|
|
46
|
+
- Create: `src/keep_npu/utilities/npu_info.py`
|
|
47
|
+
- Create: `src/keep_npu/utilities/npu_monitor.py`
|
|
48
|
+
- Create: `src/keep_npu/single_npu_controller/base_npu_controller.py`
|
|
49
|
+
- Create: `src/keep_npu/single_npu_controller/ascend_npu_controller.py`
|
|
50
|
+
- Create: `src/keep_npu/global_npu_controller/global_npu_controller.py`
|
|
51
|
+
- Create: `tests/npu_controller/*.py`
|
|
52
|
+
- Create: `tests/global_controller/*.py`
|
|
53
|
+
- Create: `tests/fixtures/npu_smi/*.txt`
|
|
54
|
+
|
|
55
|
+
**Interfaces:**
|
|
56
|
+
- Consumes: Task 1 validators and size parsing.
|
|
57
|
+
- Produces: `visible_torch_device_count()`, `list_npus()`, `NPUInfo`, `AscendNPUController`, and `GlobalNPUController`.
|
|
58
|
+
|
|
59
|
+
- [ ] Port controller contract, timing, rollback, release, and health tests with fake Torch/NPU adapters; run them and expect import failure for controller modules.
|
|
60
|
+
- [ ] Add `npu-smi` fixture tests for table parsing, missing fields, invalid utilization, inconsistent memory, and command failure; run and expect missing parser failures.
|
|
61
|
+
- [ ] Implement lazy `torch`/`torch_npu` discovery and visible ordinal selection without importing hardware libraries during local validation.
|
|
62
|
+
- [ ] Implement telemetry parsing that returns nullable fields and never converts unavailable utilization to zero.
|
|
63
|
+
- [ ] Implement chunked float32 allocation, low-cost keepalive work, monotonic interval timing, utilization backoff, runtime health, idempotent keep/release, multi-device rollback, and parallel release.
|
|
64
|
+
- [ ] Run `pytest tests/npu_controller tests/global_controller tests/utilities/test_npu_info.py tests/utilities/test_npu_monitor.py -q`; expect all selected tests to pass.
|
|
65
|
+
- [ ] Commit with `feat: add Ascend NPU controllers and telemetry`.
|
|
66
|
+
|
|
67
|
+
### Task 3: Port blocking CLI and legacy wrapper
|
|
68
|
+
|
|
69
|
+
**Files:**
|
|
70
|
+
- Create: `src/keep_npu/cli.py`
|
|
71
|
+
- Create: `tests/test_cli_thresholds.py`
|
|
72
|
+
- Create: `tests/test_cli_blocking.py`
|
|
73
|
+
- Modify: `keep_npu_alive.py`
|
|
74
|
+
- Modify: `README.md`
|
|
75
|
+
|
|
76
|
+
**Interfaces:**
|
|
77
|
+
- Consumes: `GlobalNPUController`, Task 1 validators.
|
|
78
|
+
- Produces: `keep-npu` blocking mode and compatibility wrapper behavior.
|
|
79
|
+
|
|
80
|
+
- [ ] Port the upstream blocking CLI tests with `--npu-ids`; add regression cases for `nan`, `inf`, duplicate IDs, signed zero, full-width digits, and root options before subcommands; run and expect CLI import/behavior failures.
|
|
81
|
+
- [ ] Implement the Typer root command with defaults `interval=300`, `vram=1GiB`, `busy_threshold=25`, all-visible NPUs, legacy `--threshold`, and plain validation errors.
|
|
82
|
+
- [ ] Convert `keep_npu_alive.py` into a wrapper that translates `--device`, `--interval`, and the legacy matrix-size flags into the new controller path while retaining `--once` as a bounded compatibility smoke operation.
|
|
83
|
+
- [ ] Run `pytest tests/test_cli_thresholds.py tests/test_cli_blocking.py tests/test_keep_npu_alive.py -q`; expect all selected tests to pass.
|
|
84
|
+
- [ ] Run `PYTHONPATH=src python -m keep_npu.cli --help`; expect mapped NPU options and all service subcommands.
|
|
85
|
+
- [ ] Commit with `feat: add KeepNPU blocking CLI`.
|
|
86
|
+
|
|
87
|
+
### Task 4: Port service lifecycle and service CLI
|
|
88
|
+
|
|
89
|
+
**Files:**
|
|
90
|
+
- Create: `src/keep_npu/mcp/server.py`
|
|
91
|
+
- Create: `tests/mcp/test_server.py`
|
|
92
|
+
- Create: `tests/test_cli_service_commands.py`
|
|
93
|
+
|
|
94
|
+
**Interfaces:**
|
|
95
|
+
- Consumes: `GlobalNPUController`, `list_npus()`, all shared validators.
|
|
96
|
+
- Produces: `KeepNPUServer.start_keep`, `stop_keep`, `status`, `list_npus`; CLI `serve/start/status/stop/list-npus/service-stop`.
|
|
97
|
+
|
|
98
|
+
- [ ] Port the upstream session concurrency, starting/stopping, runtime failure, release timeout, and status contract tests with the naming map; run and expect missing server failures.
|
|
99
|
+
- [ ] Port service CLI tests for local validation, auto-start rollback, machine JSON purity, malformed RPC envelopes, ownership records, and safe daemon stop; run and expect missing commands.
|
|
100
|
+
- [ ] Implement the shared session registry and lifecycle states without holding the registry lock during slow controller startup or health probes.
|
|
101
|
+
- [ ] Implement CLI RPC clients, result validators, daemon auto-start, endpoint-specific logs/PID records, ownership verification, stop-all fallback, and command hints.
|
|
102
|
+
- [ ] Run `pytest tests/mcp/test_server.py tests/test_cli_service_commands.py -q`; expect all selected tests to pass.
|
|
103
|
+
- [ ] Commit with `feat: add KeepNPU service workflows`.
|
|
104
|
+
|
|
105
|
+
### Task 5: Port REST, JSON-RPC, MCP, and dashboard
|
|
106
|
+
|
|
107
|
+
**Files:**
|
|
108
|
+
- Create: `tests/mcp/test_http_api.py`
|
|
109
|
+
- Create: `web/dashboard/**`
|
|
110
|
+
- Create: `src/keep_npu/mcp/static/index.html`
|
|
111
|
+
- Create: `src/keep_npu/mcp/static/assets/*`
|
|
112
|
+
|
|
113
|
+
**Interfaces:**
|
|
114
|
+
- Consumes: `KeepNPUServer` direct methods.
|
|
115
|
+
- Produces: REST `/api/npus` and session endpoints, JSON-RPC `/` and `/rpc`, stdio MCP lifecycle/tools, and the KeepNPU dashboard.
|
|
116
|
+
|
|
117
|
+
- [ ] Port HTTP routing, strict request-body, JSON-RPC envelope, MCP lifecycle, method/error classification, HEAD/static asset, and dashboard API tests; run and expect route/asset failures.
|
|
118
|
+
- [ ] Implement HTTP and stdio transports with exact NPU-native result keys and upstream route-hardening behavior.
|
|
119
|
+
- [ ] Port dashboard source and tests with NPU labels and `/api/npus`; run `npm test -- --run` in `web/dashboard` and expect failures before mapped components are complete.
|
|
120
|
+
- [ ] Complete the mapped React dashboard, run `npm run build`, and synchronize built assets into `src/keep_npu/mcp/static`.
|
|
121
|
+
- [ ] Run `pytest tests/mcp -q` and `npm test -- --run`; expect all selected tests to pass.
|
|
122
|
+
- [ ] Commit with `feat: add KeepNPU APIs and dashboard`.
|
|
123
|
+
|
|
124
|
+
### Task 6: Full compatibility and packaging verification
|
|
125
|
+
|
|
126
|
+
**Files:**
|
|
127
|
+
- Create/modify: mapped remaining tests under `tests/`
|
|
128
|
+
- Create: `docs/compatibility.md`
|
|
129
|
+
- Modify: `README.md`
|
|
130
|
+
- Modify: `MANIFEST.in`
|
|
131
|
+
|
|
132
|
+
**Interfaces:**
|
|
133
|
+
- Consumes: all prior public interfaces.
|
|
134
|
+
- Produces: reproducible compatibility evidence and installable artifacts.
|
|
135
|
+
|
|
136
|
+
- [ ] Port every remaining hardware-independent upstream test and run the full suite; record and fix each mapped contract failure using a failing regression test first.
|
|
137
|
+
- [ ] Run `python -m pytest -q`, `ruff check .`, and `python -m compileall -q src tests keep_npu_alive.py`; expect clean output.
|
|
138
|
+
- [ ] Build wheel/sdist, install the wheel into a temporary virtual environment, and smoke-test `keep-npu --help` plus `keep-npu-mcp-server --help`.
|
|
139
|
+
- [ ] Build dashboard production assets and verify packaged assets match the React build.
|
|
140
|
+
- [ ] Document the explicit name mapping, supported Python/CANN expectations, CLI/API examples, and known platform-only differences.
|
|
141
|
+
- [ ] Commit with `test: complete KeepGPU compatibility coverage`.
|
|
142
|
+
|
|
143
|
+
### Task 7: SSH Ascend validation and hardware corrections
|
|
144
|
+
|
|
145
|
+
**Files:**
|
|
146
|
+
- Create: `docs/validation/ascend-remote-results.md`
|
|
147
|
+
- Create/modify: telemetry fixtures and regression tests discovered from hardware.
|
|
148
|
+
- Modify: hardware modules only when a failing remote case is reproduced locally.
|
|
149
|
+
|
|
150
|
+
**Interfaces:**
|
|
151
|
+
- Consumes: built KeepNPU artifact and configured SSH hosts.
|
|
152
|
+
- Produces: remote evidence, platform corrections, and cleanup verification.
|
|
153
|
+
|
|
154
|
+
- [ ] Discover SSH host aliases read-only and preflight each reachable candidate with bounded commands for `npu-smi`, Python, CANN variables, `torch`, `torch_npu`, and device count.
|
|
155
|
+
- [ ] Select at least two usable environments, or multiple devices on one host, based on availability and current memory pressure.
|
|
156
|
+
- [ ] Rsync only source, tests, metadata, docs, and built dashboard assets to a unique `/tmp/keep-npu-<timestamp>` directory on each target.
|
|
157
|
+
- [ ] Run remote unit smoke tests, `list-npus`, a low-memory short blocking session, and before/during/after telemetry; use explicit timeouts and capture logs.
|
|
158
|
+
- [ ] Run service lifecycle, REST, JSON-RPC, MCP, dashboard endpoint, multi-NPU, invalid-selection, signal, repeated-stop, and rollback checks.
|
|
159
|
+
- [ ] For each hardware discrepancy, add a local failing fixture/regression test, implement the smallest correction, rerun locally, redeploy, and rerun the affected remote check.
|
|
160
|
+
- [ ] Stop all test sessions and services, verify no KeepNPU process remains, verify memory recovery, and remove each remote temporary directory.
|
|
161
|
+
- [ ] Write exact host/runtime/device/version/result evidence and any irreducible Ascend differences to `docs/validation/ascend-remote-results.md`.
|
|
162
|
+
- [ ] Run the complete local verification suite once more and commit with `test: validate KeepNPU on Ascend hardware`.
|