dsh-scnet 0.4.0 → 0.4.1
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.
- package/LICENSE +1 -1
- package/README.md +125 -9
- package/README_CN.md +107 -0
- package/cordis.patch.yml +8 -0
- package/docs/installation.md +60 -0
- package/docs/installation.zh-CN.md +73 -0
- package/docs/testing.md +63 -0
- package/docs/testing.zh-CN.md +62 -0
- package/package.json +13 -8
- package/skills/scnet-hpc/SKILL.md +88 -246
- package/skills/scnet-hpc/clusters/zzeshell.conf +1 -1
- package/skills/scnet-hpc/references/adding-cluster.md +13 -16
- package/skills/scnet-hpc/references/environment.md +15 -15
- package/skills/scnet-hpc/references/quickstart-en.md +4 -0
- package/skills/scnet-hpc/references/setup.md +9 -11
- package/skills/scnet-hpc/references/software-compatibility.md +6 -6
- package/skills/scnet-hpc/references/troubleshooting.md +15 -16
- package/skills/scnet-hpc/scripts/new-job.sh +5 -5
- package/skills/scnet-hpc/scripts/refresh-cluster.sh +1 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
集群的主机名、端口等参数来自 `clusters/<集群短名>.conf`。
|
|
4
4
|
本文用 `<集群>`、`<主机名>`、`<端口>` 表示从 profile 读出的值。
|
|
5
5
|
|
|
6
|
-
##
|
|
6
|
+
## 手工配置
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
9
|
# 1. 装私钥
|
|
@@ -42,14 +42,14 @@ Host <集群> <主机名>
|
|
|
42
42
|
UpdateHostKeys no
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
##
|
|
45
|
+
## SSH 选项说明
|
|
46
46
|
|
|
47
47
|
**`ControlPersist 10m` 而非 `yes`**:永久驻留的 master 在笔记本休眠或换网络后会
|
|
48
|
-
变成失效 socket
|
|
48
|
+
变成失效 socket,可能留下需要清理的失效 socket。10 分钟覆盖一次交互操作的节奏,又能自然回收。
|
|
49
49
|
实测复用后单条命令从约 2 秒降到 0.57 秒。
|
|
50
50
|
|
|
51
51
|
**`ServerAliveInterval 60`**:应用层心跳,防止空闲 SSH 会话被中间网关静默切断。
|
|
52
|
-
|
|
52
|
+
用于保持长时间空闲会话。`TCPKeepAlive` 是 TCP 层的,两者互补。
|
|
53
53
|
|
|
54
54
|
**`UpdateHostKeys no`**:部分平台的服务端对主机密钥轮换扩展返回错误签名:
|
|
55
55
|
|
|
@@ -57,9 +57,7 @@ Host <集群> <主机名>
|
|
|
57
57
|
client_global_hostkeys_prove_confirm: server gave bad signature for RSA key 0
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
告警噪音。**只在遇到这个告警的集群上加**(profile 里标
|
|
62
|
-
`NEEDS_UPDATE_HOSTKEYS_NO=yes`)。
|
|
60
|
+
该设置仅禁用服务端主机密钥轮换扩展;首次主机密钥仍按正常流程校验。仅在出现该告警且 profile 标记 `NEEDS_UPDATE_HOSTKEYS_NO=yes` 的集群上使用。
|
|
63
61
|
|
|
64
62
|
**`IdentitiesOnly yes`**:只用指定的私钥。ssh-agent 里密钥多时,避免因尝试次数
|
|
65
63
|
过多被服务端拒绝。
|
|
@@ -91,7 +89,7 @@ profile 里的 `KEY_NAME_MARKER` 就是用来从这种文件名里提取用户
|
|
|
91
89
|
`scnet-hpc` profile 使用 `_<CLUSTER_HOST>_` 占位符,所以安装时通常需要显式传
|
|
92
90
|
用户名,或在本地私有 profile 中补齐真实标记。
|
|
93
91
|
|
|
94
|
-
|
|
92
|
+
查看密钥指纹:
|
|
95
93
|
|
|
96
94
|
```bash
|
|
97
95
|
ssh-keygen -lf ~/.ssh/id_rsa_<集群>
|
|
@@ -113,7 +111,7 @@ ssh-keygen -p -f ~/.ssh/id_rsa_<集群>
|
|
|
113
111
|
| `Connection timed out` | 端口被本地网络阻断(超算常用非 22 端口)|
|
|
114
112
|
| `Bad owner or permissions on config` | `chmod 600 ~/.ssh/config` |
|
|
115
113
|
| `WARNING: UNPROTECTED PRIVATE KEY` | `chmod 600 ~/.ssh/id_rsa_<集群>` |
|
|
116
|
-
|
|
|
114
|
+
| 首次连接等待主机指纹确认 | 在等确认主机指纹,加 `-o StrictHostKeyChecking=accept-new` |
|
|
117
115
|
|
|
118
116
|
多数超算平台有 **IP 白名单**,换网络(家里/公司/热点)后可能连不上,
|
|
119
117
|
需要去控制台加当前 IP。
|
|
@@ -125,7 +123,7 @@ ssh -o BatchMode=yes <集群> '<命令>'
|
|
|
125
123
|
```
|
|
126
124
|
|
|
127
125
|
`BatchMode=yes` 让认证失败立刻返回,而不是卡在密码提示上等输入。写自动化脚本时
|
|
128
|
-
|
|
126
|
+
应启用,以避免自动化流程等待交互输入。
|
|
129
127
|
|
|
130
128
|
## 文件传输
|
|
131
129
|
|
|
@@ -135,4 +133,4 @@ scp <集群>:/public/home/$USER/scripts/logs/job_123.log .
|
|
|
135
133
|
rsync -avz --progress ./dir/ <集群>:/public/home/$USER/dir/ # 大量文件
|
|
136
134
|
```
|
|
137
135
|
|
|
138
|
-
|
|
136
|
+
上述命令复用 SSH profile 中的连接参数。
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
### 编译型软件的分层验证
|
|
12
12
|
|
|
13
13
|
- **把编译放到计算节点**:C++/HIP 大型构建的峰值内存可能远高于登录节点限额。
|
|
14
|
-
编译器进程被 OOM kill
|
|
14
|
+
编译器进程被 OOM kill 时,先换到有明确内存配额的计算作业,先排除资源限制,再判断源码问题。
|
|
15
15
|
- **只生成目标架构**:显式设置目标 `gfx` 架构。默认同时生成多个架构会成倍增加
|
|
16
16
|
编译时间、产物体积和峰值内存。
|
|
17
17
|
- **升级工具链后重跑最小构建**:DTK/编译器升级可能改变 wrapper 头、host/device
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
可见的 HSA/HIP 库或符号链接。以目标计算节点解析到的真实库文件为准,必要时通过
|
|
21
21
|
CMake cache 变量显式传入,不创建全局假链接。
|
|
22
22
|
- **先串行能力、后并行能力**:先完成无 MPI 的单卡最小构建和功能验证,再开启 MPI,
|
|
23
|
-
最后测试 GPU-aware
|
|
23
|
+
最后测试 GPU-aware 通信与多卡扩展,以隔离编译器、运行库和通信栈问题。
|
|
24
24
|
|
|
25
25
|
### GPU-aware MPI 的验证边界
|
|
26
26
|
|
|
@@ -39,7 +39,7 @@ GPU-aware on/off 对照。单节点验证可先固定共享内存与 self 传输
|
|
|
39
39
|
|
|
40
40
|
### 已验证的典型边界
|
|
41
41
|
|
|
42
|
-
- **gfx936 / BW1000**:Triton、硬件 FP8 `torch._scaled_mm`、部分 bitsandbytes INT8 路径可能不可用;纯 PyTorch
|
|
42
|
+
- **gfx936 / BW1000**:Triton、硬件 FP8 `torch._scaled_mm`、部分 bitsandbytes INT8 路径可能不可用;纯 PyTorch 软件反量化可作为兼容路径,但需要单独做性能和精度验证。
|
|
43
43
|
- **gfx906 / Z100**:CentOS 7.6 的 glibc 2.17 会限制 manylinux wheel 版本;安装 Python 软件时优先选 manylinux2014 / manylinux_2_17 兼容包。MinerU 场景中,Python 3.10 + onnxruntime 1.16.3 是已验证方向,magika 版本/API 需要随源码适配。
|
|
44
44
|
- **GROMACS HIP**:先验证 CMake 最低版本、DTK 的 `lib`/`lib64` CMake 路径、目标架构、FFTW 预置和 SIMD;CUDA 兼容层与原生 HIP 的性能不可直接互相推断。
|
|
45
45
|
|
|
@@ -55,18 +55,18 @@ echo "test_exit_code=$rc"
|
|
|
55
55
|
exit "$rc"
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
不能只依据 `sacct` 的 `COMPLETED` 判定成功。脚本必须显式传递最后一个测试命令的退出码,并同时读取 `.out/.err`。
|
|
59
59
|
|
|
60
60
|
### 公开报告模板
|
|
61
61
|
|
|
62
|
-
标题采用“项目 + 加速器/平台 +
|
|
62
|
+
标题采用“项目 + 加速器/平台 + 编译与性能/兼容性测试报告”。正文可按以下顺序:
|
|
63
63
|
|
|
64
64
|
1. 环境信息
|
|
65
65
|
2. 编译过程与主要难题
|
|
66
66
|
3. 最终方案与验证结果
|
|
67
67
|
4. 测试数据与资源占用
|
|
68
68
|
5. 已知限制与注意事项
|
|
69
|
-
6.
|
|
69
|
+
6. 适用范围与可复用结论
|
|
70
70
|
7. 附录:快速复现命令
|
|
71
71
|
|
|
72
72
|
发布前扫描:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 排查作业失败
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 作业状态与实际退出码
|
|
4
4
|
|
|
5
5
|
bash 脚本里 Python 崩了之后,bash 继续执行后面的行,作业以**最后一条命令**的退出码
|
|
6
6
|
结束。真实案例:
|
|
@@ -10,10 +10,10 @@ $ sacct -j <JOB_ID> --format=JobID,JobName,State,ExitCode,Elapsed
|
|
|
10
10
|
<JOB_ID> | example-job | COMPLETED | 0:0 | 00:34:32
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
该记录不能证明 Python 工作负载成功。Python 可能已在第 3 分钟抛出 `ValueError`,而日志末尾仍打印脚本中
|
|
14
14
|
写的 `===== COMPLETE =====`。
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
排查时先读取日志和工作负载退出码,再结合调度器 State 判断。
|
|
17
17
|
|
|
18
18
|
预防:脚本末尾写
|
|
19
19
|
|
|
@@ -43,7 +43,7 @@ sbatch: error: min tres(gres/dcu) request 0 exceeds per-job max tres limit 1
|
|
|
43
43
|
sbatch: error: QOSMinGRES
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
该分区要求每个作业至少申请 1 张 DCU。补充 `--gres=dcu:N`;纯 CPU 负载也受该分区策略约束。
|
|
47
47
|
|
|
48
48
|
### `too much memory was requested relative to the number of CPUs`
|
|
49
49
|
|
|
@@ -82,7 +82,7 @@ httpcore.ConnectError: [Errno -2] Name or service not known
|
|
|
82
82
|
### `cannot get address for 'hipDrvLaunchKernelEx' from libamdhip64.so`
|
|
83
83
|
|
|
84
84
|
Triton。DTK 26.04 的 HIP 运行时缺上游 ROCm 7 的 API,Triton 的 AMD backend 加载
|
|
85
|
-
|
|
85
|
+
即失败。该软件栈不能使用此 Triton 路径,依赖对应 Triton kernel 的框架也不适用(SGLang FP8、vLLM ROCm
|
|
86
86
|
MoE、transformers finegrained-fp8)。
|
|
87
87
|
|
|
88
88
|
郑州集群最近还会先报另一种缺库:
|
|
@@ -91,7 +91,7 @@ MoE、transformers finegrained-fp8)。
|
|
|
91
91
|
ImportError: libgcvm.so.17git: cannot open shared object file
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
-
本质相同,都是 Triton 在当前 DTK/DCU
|
|
94
|
+
本质相同,都是 Triton 在当前 DTK/DCU 软件栈上不可用,继续调整 Triton kernel 参数不能解决该运行时缺失。
|
|
95
95
|
|
|
96
96
|
### `torch._scaled_mm is only supported on CUDA devices with compute capability >= 9.0 or 8.9, or ROCm MI300+`
|
|
97
97
|
|
|
@@ -114,7 +114,7 @@ cat: No such file or directory ← 连日志都没有,因为写不进
|
|
|
114
114
|
1. `--output` / `--error` 路径里有未展开的变量(`$USER`、`$HOME`)
|
|
115
115
|
2. **日志目录不存在** —— Slurm 不会自动创建
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
处理方法:`#SBATCH` 里写完整字面量路径,提交前 `mkdir -p <日志目录>`。
|
|
118
118
|
`scripts/new-job.sh` 会展开好用户名并提示建目录。
|
|
119
119
|
|
|
120
120
|
### `module load` 静默失败:作业返回 0 但 `ROCM_PATH` 没设置
|
|
@@ -129,9 +129,9 @@ ROCM_PATH=未设置
|
|
|
129
129
|
### python exit=0 ← 作业「成功」了
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
该现象可能返回退出码 0,因此还需检查模块环境变量和探针输出。该行为已在昆山集群观测。
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
处理方法:shebang 用 `#!/bin/bash -l`,或在 heredoc 内包一层 `bash -l`。
|
|
135
135
|
`scripts/new-job.sh` 生成的脚本已经用 `bash -l`。
|
|
136
136
|
|
|
137
137
|
自检:作业里打印 `echo "ROCM_PATH=${ROCM_PATH:-未设置}"`,未设置就说明没生效。
|
|
@@ -145,7 +145,7 @@ ROCM_PATH=未设置
|
|
|
145
145
|
SyntaxError: Non-ASCII character '\xe5' ... no encoding declared
|
|
146
146
|
```
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
处理方法:作业脚本里显式加载 Python 3 module:
|
|
149
149
|
|
|
150
150
|
```bash
|
|
151
151
|
module load python/3.8.10
|
|
@@ -186,7 +186,7 @@ for i in range(torch.cuda.device_count()):
|
|
|
186
186
|
|
|
187
187
|
### 作业一直 `PD (Priority)` 不动
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
该状态表示等待调度资源。查询预计启动时间:
|
|
190
190
|
|
|
191
191
|
```bash
|
|
192
192
|
squeue -j <ID> --start
|
|
@@ -197,15 +197,14 @@ sinfo -p <分区> -o "%n %t" # 有几台 idle
|
|
|
197
197
|
|
|
198
198
|
## 调试策略
|
|
199
199
|
|
|
200
|
-
|
|
200
|
+
按成本递增的顺序执行验证,避免使用完整模型诊断基础环境问题:
|
|
201
201
|
|
|
202
202
|
1. **纯逻辑**(不需要 GPU/torch)→ 本地 Python 直接跑
|
|
203
203
|
2. **需要 torch/DCU 但数据量小** → `srun` 交互式,约 5 秒拿到节点
|
|
204
204
|
3. **小规模真实数据** → 2 分钟的 `sbatch` 探针作业
|
|
205
205
|
4. **完整模型** → 最后才做
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
再跑完整模型。如果跳过第 3 步直接跑,每轮试错 30 分钟。
|
|
207
|
+
例如,反量化实现应先通过小规模数值测试,再运行完整模型。
|
|
209
208
|
|
|
210
209
|
**探针作业模板**:只读 metadata 不加载权重,几秒就出结果:
|
|
211
210
|
|
|
@@ -222,11 +221,11 @@ with safe_open(path, framework="pt", device="cpu") as f:
|
|
|
222
221
|
# 作业跑在哪个节点
|
|
223
222
|
squeue -j <ID> -o "%N"
|
|
224
223
|
|
|
225
|
-
#
|
|
224
|
+
# 在作业运行期间检查目标节点进程
|
|
226
225
|
ssh <节点名> 'top -b -n1 -u $USER | head -20'
|
|
227
226
|
|
|
228
227
|
# GPU 占用
|
|
229
228
|
srun --jobid=<ID> --overlap rocm-smi
|
|
230
229
|
```
|
|
231
230
|
|
|
232
|
-
`--overlap` 让新的 srun
|
|
231
|
+
`--overlap` 让新的 srun 步骤共享已有作业的资源分配,避免为诊断步骤重新申请一份资源。
|
|
@@ -137,9 +137,9 @@ cat > "$OUT" <<EOF
|
|
|
137
137
|
#!/bin/bash -l
|
|
138
138
|
# 目标集群: ${CLUSTER_ID} (${CLUSTER_DESC:-$SSH_HOST})
|
|
139
139
|
#
|
|
140
|
-
#
|
|
141
|
-
# shell
|
|
142
|
-
# 返回 0,但 ROCM_PATH
|
|
140
|
+
# 使用 "bash -l",因为部分集群仅在 login
|
|
141
|
+
# shell 中定义 module 函数。普通 "#!/bin/bash" 可能使 module load 静默失败,作业仍
|
|
142
|
+
# 返回 0,但 ROCM_PATH 未设置且能力工具无输出。该行为已在昆山集群观测。
|
|
143
143
|
#SBATCH --job-name=${NAME}
|
|
144
144
|
#SBATCH --partition=${EFFECTIVE_PARTITION}
|
|
145
145
|
${GRES_LINE}
|
|
@@ -178,7 +178,7 @@ PYEOF
|
|
|
178
178
|
rc=\$?
|
|
179
179
|
echo "### python exit=\$rc"
|
|
180
180
|
date +"%Y-%m-%d %H:%M:%S"
|
|
181
|
-
#
|
|
181
|
+
# 传播工作负载退出码,避免调度器状态掩盖 Python 失败
|
|
182
182
|
exit \$rc
|
|
183
183
|
EOF
|
|
184
184
|
|
|
@@ -196,4 +196,4 @@ echo "上传并提交:"
|
|
|
196
196
|
echo " scp $OUT ${CLUSTER_ID}:${HOME_DIR}/scripts/"
|
|
197
197
|
echo " ssh ${CLUSTER_ID} 'mkdir -p ${HOME_DIR}/scripts/logs && sbatch --test-only ${HOME_DIR}/scripts/$OUT'"
|
|
198
198
|
echo
|
|
199
|
-
echo "
|
|
199
|
+
echo "要求:logs 目录必须先存在;否则作业会以 exit 53 失败且不产生日志。"
|
|
@@ -208,7 +208,7 @@ if [ "$COMPUTE" = yes ] && [ -n "$COMPUTE_OUT" ]; then
|
|
|
208
208
|
IMPORT_ERR:*) KNOWN_LIMITS_NEW="${KNOWN_LIMITS_NEW:+${KNOWN_LIMITS_NEW};}bitsandbytes 导入失败(${BNB})" ;;
|
|
209
209
|
esac
|
|
210
210
|
|
|
211
|
-
# 保留 profile
|
|
211
|
+
# 保留 profile 中已有的人工验证结论,并将动态结果置于前面。
|
|
212
212
|
if [ -n "${KNOWN_LIMITATIONS:-}" ]; then
|
|
213
213
|
OLD_IFS="$IFS"
|
|
214
214
|
IFS=';'
|