本仓库将 Hugging Face 公共模型 matrix-multiply/Congestion_Stage_Classifier(锁定上游版本 cbcbb4877f20f315531208f3265957e092a8f9d5,MIT 许可)完整适配到物理昇腾 910B4 NPU(npu:0)上进行真实推理。
推理使用镜像自带的 CANN 8.5.1 配套 torch 2.9.0+cpu + torch_npu 2.9.0,未替换任何官方 wheel,也未做 CPU 静默回退。两个完整 checkpoint(bottleneck.pt、ring.pt)已随本仓库携带(model/),SHA256 已锁定到上游精确版本,因此本仓库可独立复现。
说明:
README.md与readme.md为字节级一致的两个副本,便于区分大小写的发布平台展示。
本仓库适配的公共 MIT 模型 matrix-multiply/Congestion_Stage_Classifier 用于替换无法访问的 gagansuie/oxidize-models(原始仓库对已认证的 AtlasLeong 账号返回 404,且不存在精确的公开镜像)。本仓库以独立的仓库身份发布,不代表与 gagansuie/oxidize-models 等价,也不暗示两者在模型、权重、语义或性能上相同。本仓库仅发布 MIT 许可的 matrix-multiply/Congestion_Stage_Classifier 的 NPU 推理适配。
Congestion_Stage_Classifier 是一个固定结构的全连接 MLP 分类器,用于对“网络拥塞阶段(congestion stage)”相关的 20 维数值特征向量进行分类。
架构(由上游 state_dict 张量形状确定):20 -> 32 -> 16 -> 6
| 层 | 形状 | 说明 |
|---|---|---|
fc1 | Linear(20, 32) | 全连接 + ReLU |
fc2 | Linear(32, 16) | 全连接 + ReLU |
fc3 | Linear(16, 6) | 输出层(线性,logits,无激活) |
cbcbb4877f20f315531208f3265957e092a8f9d5model/bottleneck.pt → c6c82ac48f62da0bec76a6f45cded37486fffea14254807ff940c006cd287a02model/ring.pt → 548cabc8aef485e1f38efe05d1d717ca0a027047844906305f9b53b3a9c20958network-congestion-stage-classificationtorch_npunpu:0上游仓库未公开 20 个输入特征的具体语义/顺序,也未公开 6 个输出类别的语义标签。因此本仓库不发明任何标签或特征名,只输出:
argmax)本仓库使用的确定性 20 维测试向量仅为 smoke / acceptance 向量,不构成有语义含义的样本。
本仓库在以下已验证环境中运行:
| 组件 | 版本 | 说明 |
|---|---|---|
| 操作系统 | 容器环境(Linux,aarch64) | 私有 PID namespace 容器 |
| 硬件 | Ascend 910B4-1(8 卡物理设备;本任务使用 npu:0) | npu-smi info 可见 |
| CANN | 8.5.1 | /usr/local/Ascend/cann-8.5.1 |
| Driver | 25.5.1 | /usr/local/Ascend/driver/version.info |
| Python | 3.11.14 | /usr/local/python3.11.14/bin/python3 |
| torch | 2.9.0+cpu | 镜像自带,禁止替换 |
| torch_npu | 2.9.0 | 镜像自带,禁止替换 |
| numpy | 1.26.4 | 唯一非 torch 依赖 |
重要:
torch与torch_npu由容器镜像按 CANN 版本配套提供,绝不能用普通 PyPI wheel 替换。本仓库requirements.txt只列出必要的非 torch 依赖(numpy==1.26.4)。
export PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/
export PIP_TRUSTED_HOST=mirrors.aliyun.com
cd congestion-stage-classifier-npu
pip install -r requirements.txtrequirements.txt 内容:
numpy==1.26.4(torch / torch_npu 不列入其中,由 CANN 配套镜像提供。)
# 确认 NPU 可见
npu-smi info
# 确认 torch_npu 可用
python3 -c "import torch, torch_npu; print(torch.__version__, torch_npu.__version__); print(torch.npu.is_available(), torch.npu.get_device_name(0))"cd congestion-stage-classifier-npu
python3 -u inference.py \
--model-dir model \
--device npu:0 \
--iterations 2000 \
--warmup 10 \
--hold-secs 4 \
--output-json logs/npu_result.json \
--npu-smi-log logs/npu_smi_capture.txt参数说明:
| 参数 | 默认值 | 说明 |
|---|---|---|
--model-dir | <脚本目录>/model | 存放 bottleneck.pt 与 ring.pt 的目录 |
--device | npu:0 | NPU 设备;必须是 npu:<id> |
--output-json | logs/npu_result.json | 结构化结果 JSON 输出路径 |
--npu-smi-log | logs/npu_smi_capture.txt | 并发采集的原始 npu-smi 输出 |
--iterations | 2000 | 每个 checkpoint 的计时迭代次数 |
--warmup | 10 | 不计时预热迭代次数 |
--hold-secs | 2.0 | 采集 npu-smi 时保持 NPU 上下文忙的秒数 |
import torch_npu 失败 → 非零退出。torch.npu.is_available() == False 或设备数 < 1 → 非零退出。torch.load(..., weights_only=True) + model.load_state_dict(..., strict=True)。20->32->16->6(fc1(32,20)、fc2(16,32)、fc3(6,16))。npu:0,断言 model/input/logits/probabilities 均在 npu:0。torch.npu.synchronize() 后计时;拒绝非有限(NaN/Inf)输出。logs/npu_result.json。确定性 20 维测试向量(smoke / acceptance 向量,无上游语义):
[0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00,
0.00, 0.25, 0.50, 0.75, 1.00, -0.50, 0.00, 0.50, -1.00, 0.00]inference.py 内硬编码的确定性字面量。python3 -u inference.py --iterations 2000 --warmup 10 --hold-secs 4 \
--output-json logs/npu_result.json --npu-smi-log logs/npu_smi_capture.txtlogs/inference.log,已脱敏){
"pid": 24262,
"device": "npu:0",
"npu_device_name": "Ascend910B4-1",
"engine": "torch_npu",
"exit_code": 0,
"pid_matched": false,
"output_text": "bottleneck.pt: logits=[-0.897238612, 1.545307279, 7.385250092, -28.052904129, -0.684915721, -23.1659832] probs=[0.000252031, 0.002898936, 0.996537447, 0.0, 0.000311649, 0.0] predicted_class_index=2 (elapsed_s=0.314858) | ring.pt: logits=[-30.41983223, -6.374480247, -29.689096451, -81.469749451, -14.780595779, -1712.715087891] probs=[0.0, 0.999776542, 0.0, 0.0, 0.000223446, 0.0] predicted_class_index=1 (elapsed_s=0.303483)",
"result_json": "logs/npu_result.json"
}备注:运行日志开头可能出现
path string is NULL字样,这是容器内 CANN 运行时的一条良性提示,不影响 NPU 推理结果与退出码。
结构化结果见 logs/npu_result.json(exit_code = 0,npu_available = true,所有 placement 均在 npu:0)。
| 字段 | 值 |
|---|---|
engine | torch_npu |
torch / torch_npu | 2.9.0+cpu / 2.9.0 |
cann_version / driver_version | 8.5.1 / 25.5.1 |
npu_device_name | Ascend910B4-1 |
npu_device_count(torch 可见) | 1 |
npu_physical_device_count(npu-smi) | 8(id 0–7) |
devices | ["npu:0"] |
pid | 24262 |
input_device / model_device / logits_device / output_device | 全部 npu:0 |
| checkpoint | logits(6 维) | probabilities(6 维) | predicted_class_index | 单次计时 |
|---|---|---|---|---|
bottleneck.pt | [-0.8972, 1.5453, 7.3853, -28.0529, -0.6849, -23.1660] | [0.0003, 0.0029, 0.9965, 0.0, 0.0003, 0.0] | 2 | 0.314858 s / 2000 it(0.157 ms/it) |
ring.pt | [-30.4198, -6.3745, -29.6891, -81.4697, -14.7806, -1712.7151] | [0.0, 0.9998, 0.0, 0.0, 0.0002, 0.0] | 1 | 0.303483 s / 2000 it(0.152 ms/it) |
注意:不提供任何类别标签。
predicted_class_index仅为 0–5 的数值索引。
在推理进行中并发执行 npu-smi info 与 npu-smi info -t proc-mem -i 0:
baseline_rows = [])。1755882,160 MB)。1755882 仅在本次推理期间出现,且不在基线中 → 归因于本推理进程。npu-smi 只能报告 host 侧 PID,无法字面显示容器内 Python PID 24262,因此 pid_matched = false。模型/输入/logits/probabilities 的 placement 字段(全部 npu:0)进一步证明推理在 NPU 上执行。原始并发采集见 logs/npu_smi_capture.txt、logs/npu_smi_shell.log。
以下四张图片均由真实脱敏日志程序化渲染,未手工编造任何数值:




# 语法检查
python3 -m py_compile inference.py
# SHA256 校验
sha256sum -c SHA256SUMS
# 交付校验器(可选,仓库内脚本)
python3 /work/pipeline/skills/adapting-models-for-ascend-npu/scripts/validate_delivery.py .inference.py、requirements.txt、readme.md / README.md(字节一致)、.gitignore、model/bottleneck.pt、model/ring.pt、assets/*.png、logs/*.log、logs/npu_result.json、logs/npu_smi_capture.txt、SHA256SUMS。npu:0、输出有限、exit_code=0、SHA256 匹配、无 __pycache__ / *.pyc / fusion_result 等禁用产物。