打比赛最怕的不是模型调不动,而是环境反复掉链子。网页容器 4 小时过期、SSH 一断训练就挂、换个节点又要重新配环境…… 这些看起来是小事,但一天反复几次非常搞心态。
这赛季我们的解法就三个:镜像固化环境、Zellij 保住会话、固定节点避免重复编译。这三件套用熟了,比赛日常会稳很多。
## 一、SIF 镜像 :把环境 “打包带走”
SIF 是 Apptainer/Singularity 的镜像格式,一次构建,到处运行,而且不需要 root 权限。
比赛官方给的基础环境通常是 Docker 镜像(SCNet 上创建容器时 "开发镜像" 那一栏就是),需要我们自己用 Apptainer 把它转成 SIF:
```
# 把官方 Docker 镜像转成 SIF
# 具体地址在 SCNet 的"镜像管理"里复制
apptainer pull docker://<你的镜像地址>
# 转好后会生成一个 .sif 文件,放到个人目录或共享目录
mkdir -p /path/to/your/images
mv your-image.sif /path/to/your/images/pra2026.sif
```
转成 SIF 之后,直接存在节点本地或共享目录里,想用多久用多久:
```
# 运行训练
apptainer exec /path/to/your/images/pra2026.sif python train.py
# 运行评测
apptainer exec /path/to/your/images/pra2026.sif bash run_eval.sh
```
如果镜像在共享存储上,团队几个人可以共用同一份,不用担心 “我这边能跑,你那边缺依赖”。
## 二、Zellij:终端里的 “保险箱”
Zellij 是一个终端复用器,和 tmux、screen 同类,但界面更现代、上手更简单。
比赛集群一般通过 SSH 登录,网络不稳定或者电脑休眠时,SSH 一断,前台跑的任务可能直接被杀。Zellij 的作用就是把会话留在服务器上,你本地终端只是 “连上去看”。
### 2.1 安装 Zellij
如果登录节点没有预装:
```
# 方法1:cargo 安装(需要 Rust 环境)
cargo install zellij
# 方法2:直接下载 release 二进制
wget https://github.com/zellij-org/zellij/releases/download/v0.40.1/zellij-x86_64-unknown-linux-musl.tar.gz
tar -xzf zellij-x86_64-unknown-linux-musl.tar.gz
chmod +x zellij
mkdir -p ~/.local/bin
mv zellij ~/.local/bin/
export PATH=$HOME/.local/bin:$PATH
```
### 2.2 常用流程
```
# 登录集群后,先开会话
zellij --session pra
# 里面可以分屏:左代码、中日志、右终端
# 退出时直接关闭窗口,任务继续跑
# 重新 ssh 回来后,attach 回去
zellij attach pra
```
⚠️ **关键提醒**:Zellij 会话绑定在登录节点上。如果这次在 login01 开的,下次必须从 login01 attach 回去。各登各的节点,换机器就找不到会话了。
## 三、为什么要固定节点
SIF 运行时会往节点本地写缓存、编译中间文件,比如 PyTorch 的 JIT 缓存、ROCm 的编译产物。这次在 A 节点跑得好好的,下次换到 B 节点,可能又要重新拉镜像、重新 warm up,白白浪费十几分钟。
所以队伍里最好约定一个固定登录节点,比如 login01,大家都从这一个节点进。
## 四、我们日常的工作流
1. 固定节点登录
```
ssh user@login01
```
2. 进入 Zellij 会话
```
zellij attach pra
# 如果不存在,用 zellij --session pra 新建
```
3. 在会话里起镜像跑任务
```
apptainer exec /path/to/your/images/pra2026.sif srun python train.py
```
4. 退出终端后,任务仍在服务器上运行
## 五、常见问题与踩坑
**Q1:Apptainer pull 很慢 / 失败怎么办?**
A:Docker 镜像通常很大,可以换网络空闲时段重试,或者先把镜像下载到有代理的机器再传到集群。
**Q2:SIF 文件占多大空间?**
A:一般几个 GB 到十几个 GB,建议放在 `/public/home/<用户名>` 这种持久化目录,不要放在容器本地。
**Q3:Zellij attach 提示 session not found?**
A:大概率是你上次在 login01 开的,这次连到了 login02。退出重新 ssh 到正确的登录节点。
**Q4:队友用同一份 SIF 怎么共享?**
A:把 SIF 放在队伍都有读权限的共享目录里,或者每个人 apptainer pull 一次存在自己目录。
## 总结
- SIF 镜像:解决环境过期、依赖不一致
- Zellij 会话:解决 SSH 断开、终端关闭导致训练中断
- 固定节点:解决重复拉镜像、重复编译的隐性时间浪费
这三件套都不涉及比赛规则外的操作,只是让工具用得顺手一点。如果你也正在被网页容器和断网折磨,建议试试。
---
本文为原创文章,采用 CC BY-SA 4.0(署名 - 相同方式共享 4.0)协议分发。转载需注明原作者与原文链接,衍生作品须使用相同协议。
首发链接:[https://blog.csdn.net/2501_94451885/article/details/163109888](https://blog.csdn.net/2501_94451885/article/details/163109888)