前一阵子在智星云上调深度学习模型,连续租了好几台不同型号的GPU实例。真正让我头疼的倒不是模型不收敛,而是“数据怎么传上去”“环境怎么每次保持一致”“换一台机器后怎么快速恢复现场”。说白了,就是GPU算力平台上的数据共享和镜像制作这两件事。刚开始我把它们想简单了,结果光是在“传数据→装环境→跑崩→释放实例→再租一台→从头再来”这个循环里,就浪费了大把时间和算力费用。
这篇把我在智星云上的完整实践整理出来,覆盖数据共享的几种主流姿势、镜像制作的底层原理和完整操作步骤,以及我实际操作中踩过的一些坑和对应的排查办法。不管你是第一次接触GPU云平台的算法新人,还是已经跑过几次训练但一直被环境问题折磨的工程师,这篇都值得存下来慢慢看。
1. 项目引入:为什么GPU算力平台逃不掉“数据共享”和“镜像制作”这两件事
1.1 谁需要看这篇,能解决什么具体痛点
现在做AI训练的同学,几乎绕不开GPU算力平台。本地显卡不够用,公司服务器排队排到天荒地老,租云GPU成了最常见的选择。但云GPU和我们自己桌上的电脑不一样,它是一台“用完就还”的机器——实例释放后,系统盘上的东西不一定还在,更麻烦的是每次新租一台实例,你都要把依赖环境重新装一遍。
我见过不少人的使用习惯是这样的:租一台实例,SSH连上去,先花半小时装CUDA、装PyTorch、装各种依赖,再花半小时传数据,然后开始训练。训练中断了,实例释放了,下次再租一台,又重新来一遍。一周下来,真正跑模型的时长也许只有租用时长的三分之一,其他时间全耗在环境准备和数据搬运上。
如果你也有下面这些感受,那这篇就是给你写的:
- 每次换实例都要重新装环境,少则半小时,多则一小时起步。
- 手动上传几十GB数据集,控制台上传到一半就断线或者直接卡死。
- 团队里几个人共用一套GPU资源,环境版本不统一,同一份代码在不同机器上跑出不同结果。
- 训练完想保存当前环境,却不知道“保存镜像”到底会保存什么、会不会把系统搞坏。
这些问题的核心,都可以归到两个动作上:一是数据怎么高效地进入和离开实例,二是环境怎么做成镜像实现“一键恢复”。把这两件事理顺,你使用GPU云平台的效率会明显提升。
1.2 先厘清概念:GPU云平台的“镜像”到底是个什么
说到镜像,很多老玩家第一反应是早年用Ghost给Windows做C盘备份。说实话,GPU云平台上的镜像,思路和Ghost很接近——它就是整块系统盘的一个完整快照。有点像你装完系统、装好所有软件、配好环境之后,给整个C盘打包备份一次。之后不管哪台机器,只要用这个镜像启动,就能得到一个和备份时几乎一模一样的环境。
智星云这类GPU算力平台上,镜像中通常包含这几样东西:
- 操作系统本身,比如Ubuntu 20.04或22.04。
- GPU驱动、CUDA Toolkit、cuDNN这些底层计算库。
- Python解释器以及通过conda或pip安装的所有包。
- 你放在系统盘里的代码、配置文件和预处理好的小规模数据。
- 一些系统级设置,比如环境变量、系统服务、登录账号等。
这里要和另一种“镜像”区分开:Docker镜像。Docker镜像是打包应用和依赖的,但它和GPU云平台所说的“实例镜像”不是一个层级。GPU云平台的镜像保存的是整个虚拟机或物理机系统盘的状态,粒度更粗,也更彻底。也就是说,镜像做出来之后,里面所有东西都会原样保留,不需要你再执行docker commit或重新build。
1.3 实例、镜像、数据盘:三个角色的分工
在实际操作前,先把三个概念理清:
- 实例:你实际租到的一台GPU机器,有CPU、内存、GPU、系统盘,可以通过SSH或Web终端登录使用。
- 镜像:实例系统盘在某一个时刻的“备份照片”。你可以用镜像创建一台全新的实例。
- 数据盘(有些平台叫数据盘或共享存储):独立于系统盘的一块存储空间,主要用来放大体量数据。数据盘最典型的特点是,实例释放后数据可能仍然保留,下次还可以挂载回来。
简单理解:镜像是“环境”,数据盘是“资料”。环境可以频繁打包复制,资料则应该放在独立的持久化存储里,不要和系统盘混在一起。
我在实际项目里有一条比较规律的分工:系统盘只放操作系统、CUDA、conda环境和代码仓库;所有训练数据集、输出模型、日志文件,全部放到数据盘或对象存储里。这样镜像体积小、制作快,数据也不容易因为实例释放而丢失。这条分工在后面镜像制作章节会反复用到。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 数据共享实战:把数据送进GPU实例的几种主流姿势
2.1 控制台上传下载:适合小文件和临时调试
所有GPU算力平台基本都会提供一个网页版文件管理功能,智星云的控制台里也有。你可以直接在浏览器里选择本地文件上传到实例的某个目录,也可以从实例下载文件到本地。
这个方式好用是好用,但它有明显的边界:
- 单文件大小通常有限制,有的平台限制单文件2GB或5GB,超过就上传失败。
- 大文件上传时,网页连接一旦超时或刷新,进度就丢了,没有断点续传能力。
- 大量小文件通过网页上传会非常慢,因为每个文件都要建立一次HTTP连接,延迟高且容易失败。
所以我给控制台上传功能的定位是:调试用的临时小文件、配置文件、或者几百MB以内的模型权重,用网页上传最方便。但只要是GB级别的数据集,或者成千上万张小图片,一定要转向命令行或对象存储方案,别在网页上传上死磕。
2.2 scp/rsync:批量大文件的正确姿势
命令行传输是我在智星云上最常用的数据传输方式。优点是稳定、支持断点续传、可以通过SSH密钥免密登录,而且一次能传超大文件,不受网页限制。
最基本的scp用法是这样:
bash复制# 从本地传单个文件到远端实例
scp -P 2222 ./model_epoch_100.pth root@8.xxx.xxx.xxx:/root/data/
# 从远端实例下载文件到本地
scp -P 2222 root@8.xxx.xxx.xxx:/root/output/result.json ./
需要注意,智星云实例的SSH端口不一定是默认的22,控制台里会显示具体端口,所以加了-P参数指定远程端口。如果是密钥登录,还要加上-i参数指定私钥文件。
scp适合一次性传输,但它有个缺点:传输中断后,重新执行会从头开始,不会接着上次的进度传。这时候就该用rsync了:
bash复制# rsync 支持断点续传、增量同步、压缩传输
rsync -avP -e "ssh -p 2222" ./datasets/ root@8.xxx.xxx.xxx:/root/datasets/
这里的参数解释一下:
- -a:归档模式,保留文件属性、时间戳、软链接。
- -v:显示传输过程。
- -P:等于--partial加上--progress,支持断点续传并显示进度。
- -e:指定SSH命令和端口。
rsync最实用的场景是:你传了20GB数据,网络断了,重新执行一遍同样的命令,它会自动跳过已经传输完成的文件,只把剩余部分补齐。这在弱网环境下简直是救命的。
另外还有一个实操心得:传大量小文件时,一定要先打包再传。比如你有一个数据目录,里面有10万张小图片,直接rsync会因为大量小文件的IO开销而慢得离谱。正确的做法是先在本地打包成tar文件:
bash复制tar -czf datasets.tar.gz ./datasets/
# 传压缩包
rsync -avP -e "ssh -p 2222" datasets.tar.gz root@8.xxx.xxx.xxx:/root/data/
# 到实例上解压
tar -xzf datasets.tar.gz -C /root/data/
打包后单文件传输效率远高于散文件,而且还能通过压缩减小传输量。如果数据集本身是图片、视频这类高度可压缩的文件,压缩率会很可观。
最后提醒一点:长传大文件时,最好在tmux或screen会话里执行,这样即使你的SSH连接断开,传输进程也能在远端继续跑。这也是我吃过亏后养成的习惯。
2.3 对象存储中转:超大文件和多人协作的更优解
当数据量达到几十GB甚至几个TB的时候,直接从本地传到GPU实例就不是最优方案了。一方面受限于你本地上行带宽,另一方面一旦传输中断,重传成本很高。更稳妥的做法是把数据先放到对象存储里,再由GPU实例从对象存储拉取。
对象存储大家应该不陌生,就是OSS、COS、S3这类服务。操作思路很简单:
第一步,在本地把数据上传到对象存储桶:
bash复制# 以OSS的ossutil为例
./ossutil cp -r ./datasets/ oss://my-bucket/datasets/
第二步,到GPU实例上把数据下载下来:
bash复制# 使用预签名URL,临时下载链接
wget -c -O datasets.tar "https://my-bucket.oss-cn-xxx.aliyuncs.com/datasets.tar?signature=xxx"
wget的-c参数支持断点续传,就算下载中途断了,重新执行也能接着下。
使用对象存储中转有三大好处:
- 上传带宽由本地上行决定,下载带宽由GPU实例所在机房决定,而GPU机房通常都是万兆内网或高速公网,拉取速度极快。
- 数据放桶里后,可以同时被多台实例拉取,不用重复上传。
- 实例释放后,数据依然在桶里,不会被清理。
有些平台还提供内网OSS地址,GPU实例通过内网地址拉取对象存储数据,走的是内网流量,速度更快、还免公网流量费。这个细节值得重点留意,能省下不少时间。
2.4 多实例、多人协同的数据同步技巧
除了和本地传数据,实际项目里还经常需要在多台GPU实例之间同步数据。比如同一个团队在多个节点上跑消融实验,每台机器都需要同一份数据集。
一个土办法是:在一台实例上把数据整理好,然后起一个临时HTTP服务,让其他实例拉取:
bash复制# 在“源实例”上,进入数据目录并启动HTTP服务
cd /root/datasets
python3 -m http.server 8899
其他实例上执行:
bash复制wget -c http://源实例IP:8899/datasets.tar.gz
这种方式适合集群内部临时分发,速度快、配置简单。不过要确认安全组规则放行了对应端口。
另外一种做法是把数据放到平台提供的共享存储或网盘目录里。智星云也提供了文件存储功能,可以把同一个存储目录挂载到多台实例上,多台机器读写同一份数据。这种方式最适合团队协作场景,避免数据拷贝不一致的问题。
最后再强调一条:数据版本管理。无论用什么方式共享数据,给数据集加上版本号是一个好习惯,比如datasets_v3_20250115.tar。不然团队里几个人各传各的,最后谁都不知道当前跑的是哪个版本,这种混乱比网络中断更让人崩溃。
3. 镜像制作前的底层认知与检查清单
3.1 镜像保存的底层原理:它到底保存了什么
我最初接触“保存镜像”这个功能时有个误解,以为它只是把conda环境导出一下,或者相当于把安装的Python包列个清单。后来实际操作才发现,智星云这类平台上的镜像功能,保存的是整个系统盘的块级别快照。
用一句话解释:镜像是把当前系统盘的完整状态打包下来,里面包括操作系统、驱动、已安装软件、环境变量、用户数据,一切都在。之后你用这个镜像创建新实例时,新实例的系统盘就是那个时刻的完整拷贝,相当于“时间倒流”回到保存镜像的那个瞬间。
这意味着两件事:
第一,你在系统盘上做的一切都会被保存下来。如果你已经上传了数据到系统盘,这些数据也会跟着进镜像,镜像体积会明显增大。所以制作镜像前,最好把临时数据、缓存文件清理干净。
第二,镜像保存的是系统盘,而不一定包括数据盘。数据盘通常是独立存储,不会自动包含在系统盘镜像里。
我个人的经验是:制作镜像时,只保留“环境”相关的内容,把“数据”排除在外。这样镜像体积小,保存速度快,也更方便在不同项目间复用。
3.2 制作镜像前必须检查的四件事
明确镜像保存范围后,我每次制作镜像前都会按固定清单检查一遍,避免做完一个“废镜像”或者镜像体积失控。
第一,确认GPU驱动和CUDA版本符合预期。在实例里执行nvidia-smi,查看驱动版本和CUDA版本;再执行nvcc -V,确认CUDA Toolkit版本。这两个版本要记录下来,后续在镜像命名或文档里注明。
第二,确认conda环境列表。执行conda env list,看看当前都有哪些环境。如果环境太多,建议把用不到的环境直接删掉,镜像是全量快照,多一个环境就多占一份空间。
第三,清理临时文件和缓存。下面这条命令组合拳,能把常见的缓存清得比较干净:
bash复制# 清理conda缓存
conda clean -a -y
# 清理pip缓存
pip cache purge
# 清理系统apt缓存
apt-get clean
rm -rf /var/lib/apt/lists/*
# 清理临时目录
rm -rf /tmp/*
第四,检查系统盘剩余空间。执行df -h /,如果系统盘空间已经用了90%以上,建议先做一次清理再保存镜像,否则保存过程可能因为空间不足而失败。
3.3 控制镜像体积的具体做法
镜像体积直接关系到两个问题:保存时间、存储费用。一个镜像如果是10GB,保存可能只要几分钟;如果膨胀到100GB,保存时间可能长达半小时,而且镜像仓库存储费用也会更高。
想控制体积,除了清理缓存,还可以从这几方面入手:
- 不要用conda安装大型CUDA包,优先用系统级CUDA或者显式指定版本。有些同学为了省事,直接用
conda install cudatoolkit,会安装很多用不到的组件。 - 数据文件不要放系统盘。如果已经放上去了,制作镜像前移到数据盘或直接删除。
- 不要保留多个大版本的模型权重。在制作镜像前,临时清理掉旧checkpoint,只保留最新的几个。
- 如果只是装了测试用的包,最好卸载。比如你不小心装了一个几GB的Gradle或Android SDK,这些都会进入镜像。
一个合理的镜像体积,我建议控制在20GB以内。如果超过这个数,先检查一下是不是有意外的大文件进了系统盘。
4. 实操:在智星云上制作一份可复用的GPU训练环境镜像
4.1 选择合适的公共镜像完成首次开机
制作自定义镜像的第一步,是先租一台实例,并选一个尽可能接近你需求的公共镜像作为底座。
智星云控制台里一般会有不少现成的公共镜像,比如PyTorch版、TensorFlow版、纯系统版等。怎么选?我的建议是:优先选“系统镜像+预装了对应版本CUDA”的类型,而不是带有大量深度学习框架的镜像。
理由很简单:公共镜像里预装的框架版本不一定符合你的代码需求。与其在别人的环境上改来改去,不如从一个干净的系统镜像起步,自己按需安装,这样最后做出来的镜像才是真正精通自己需求的。
不过,如果你用的是比较常见的框架组合,比如PyTorch 2.3 + CUDA 12.1 + Python 3.10,直接选预装PyTorch的公共镜像能省不少时间。这个看个人取舍,第一次做镜像我建议选轻量系统镜像,后面熟练了可以选带框架的镜像加速。
实例启动后,先用SSH登录,确认GPU状态:
bash复制nvidia-smi
如果nvidia-smi正常输出GPU信息,说明驱动已经装好。如果提示找不到命令,那就要先安装GPU驱动,这一步比较耗时,不过智星云的大多数公共镜像都已经预装驱动,通常不会有这个问题。
4.2 驱动、CUDA、cuDNN版本确认与安装策略
登录实例后,先不要急着装Python包,先把底层的CUDA版本确认清楚。
执行nvidia-smi看右上角的CUDA Version,这个数值表示驱动支持的最高CUDA版本,但不代表系统里已经装了对应版本的CUDA Toolkit。再执行nvcc -V,这个才是CUDA Toolkit编译器版本。很多时候两者不一致,这是正常的。
比如nvidia-smi显示CUDA Version: 12.4,但nvcc -V显示的是11.8,说明驱动支持12.4,但你实际安装的工具链是11.8。很多深度学习框架其实是通过自带CUDA runtime运行的,不依赖系统级CUDA Toolkit,所以系统NVCC版本不是铁律。PyTorch的pip包会自带CUDA运行库,你只需要保证GPU驱动版本不低于PyTorch要求的版本即可。
实际训练时常见的版本对应关系大概是:
- PyTorch 2.x + CUDA 12.1,需要GPU驱动版本大于等于525。
- PyTorch 1.13 + CUDA 11.7,需要GPU驱动版本大于等于450。
- TensorFlow 2.12要求CUDA 11.8,驱动同样满足即可。
如果打算用conda install pytorch ... -c pytorch安装PyTorch,一般会自动带上配套的CUDA库,不需要单独安装cudatoolkit。但如果你要编译自定义CUDA算子,就需要系统级CUDA Toolkit了,这时再通过conda或官方runfile安装对应版本。
cuDNN的安装逻辑类似。深度学习框架通常自带cuDNN,只有手动编译或使用特殊框架时才需要手动安装。这里我建议:如果框架不需要,就不用装,减少镜像体积。
4.3 用Conda管理Python环境和依赖
环境管理这一环,我的首选是Miniconda,而不是直接在系统Python里pip install。原因是conda可以对Python版本、CUDA相关库、科学计算库做更细粒度的管理,环境互相隔离,不会把系统Python搞乱。
安装Miniconda在公共镜像上很直接:
bash复制wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh -b -p /root/miniconda3
安装完成后激活conda:
bash复制eval "$(/root/miniconda3/bin/conda shell.bash hook)"
conda init bash
然后创建我们的训练环境:
bash复制conda create -n train python=3.10 -y
conda activate train
接下来安装PyTorch。这里不要随便pip install torch,建议去PyTorch官网查对应CUDA版本的安装命令。比如CUDA 12.1版本:
bash复制pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
这一步是安装过程的大头,会把PyTorch及其CUDA运行库一起装好。安装完成后,务必验证一下:
bash复制python -c "import torch; print(torch.__version__); print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0))"
如果输出True和GPU型号,说明PyTorch能正常调用GPU,环境就基本可用了。
其他依赖包按项目需求安装就行。这里有一个建议:把项目依赖写进requirements文件,方便以后在别的地方复现:
bash复制pip freeze > /root/requirements.txt
也可以把conda环境导出为yaml文件:
bash复制conda env export > /root/environment.yml
这两份文件是环境的“备份保险”,即使镜像出了问题,你还能从零重建环境。
4.4 预置代码、数据与启动脚本
环境装好后,把代码仓库clone下来,或者通过前面说的scp/rsync上传到实例。我习惯的目录结构是这样:
bash复制/root/
├── miniconda3/
├── project/
│ ├── code/
│ ├── env.yml
│ ├── requirements.txt
│ └── run.sh
└── data/
建议/root/data只放小规模测试数据,完整训练数据放数据盘。如果代码需要从数据盘读取数据,可以在代码里用软链接或环境变量约定路径。
一个比较实用的技巧是写一个启动脚本,把激活环境、设置环境变量、启动训练的步骤固化下来:
bash复制#!/bin/bash
# run.sh
set -e
eval "$(/root/miniconda3/bin/conda shell.bash hook)"
conda activate train
export PYTHONUNBUFFERED=1
cd /root/project/code
python train.py --config config/exp.yaml
脚本加上执行权限:
bash复制chmod +x /root/project/run.sh
有了这个脚本,每次创建新实例后,只需要执行bash /root/project/run.sh就能把整个训练流程拉起来,不用再手动敲一堆命令。
4.5 保存镜像:控制台操作与等待时间
在实例状态一切正常、所有环境配置就绪后,就可以保存镜像了。
操作路径一般在智星云控制台的“我的实例”或“全部实例”页面,找到目标实例,点击“保存镜像”按钮。系统会让你输入镜像名称和描述,确认后开始制作镜像。
这里有几个关键点:
- 保存镜像时,实例不一定要关机,但建议先执行
sync命令,把缓存中未写入磁盘的数据落盘,避免保存时文件系统处于不一致状态。 - 保存过程中实例可以继续使用,但CPU和磁盘IO可能会被占用,训练任务可能变慢。如果有紧急训练任务,建议等训练结束再保存。
- 保存需要的时间大致和系统盘已用空间成正比。10GB的镜像可能耗时几分钟,50GB可能要十几分钟甚至更久。
镜像保存完成后,会出现在“镜像列表”或“镜像仓库”里,这就是你的私有镜像。
4.6 从镜像创建新实例验证“一次点亮”
镜像做出来,不验证等于白做。我习惯的做法是:保存完镜像后,马上用这个镜像创建一台新的测试实例,验证环境是否真的可用。
创建实例时,镜像来源选择“我的镜像”或“私有镜像”,然后选刚才保存的镜像。实例启动后,依次验证:
bash复制nvidia-smi
conda env list
conda activate train
python -c "import torch; print(torch.cuda.is_available())"
如果nvidia-smi正常、conda环境存在、PyTorch的CUDA可用性为True,说明镜像制作成功。再跑一段小测试代码,确认训练流程能完整跑通,这个镜像就能放心上线使用了。
我踩过的坑是:有时候保存镜像时,conda环境在/root/miniconda3下,但新实例登录用户变了一个,导致conda activate找不到环境。遇到这种情况,记得检查一下登录用户是否正确,或者把conda环境的路径添加到新用户的.bashrc里。
5. 常见问题与排查技巧实录
5.1 镜像保存卡住或一直失败
镜像保存过程中卡住,最常见的原因是系统盘空间占满,或者实例上有大量的文件写入导致快照无法完成。如果你遇到保存镜像一直卡在某个进度,先执行df -h /看下系统盘空间,然后清理缓存文件再重试。
另外一个比较隐蔽的原因是:系统盘中有海量小文件,比如site-packages里大量Python包源文件、缓存文件。这种情况下,快照服务遍历文件会很慢。解决办法是在制作镜像前清理缓存,尤其清理pip cache、conda cache以及各用户目录下的缓存文件。
如果反复失败,还可以考虑创建一个新实例,在新实例上重新配置环境再保存镜像。有时候当前实例的系统已经进入一种诡异的“坏状态”,与其排查到底,不如换一台干净实例重来一次,效率更高。
5.2 换机器换GPU后报CUDA错误
这个问题的典型场景是:用同一份镜像在新实例上启动,结果程序报错说CUDA driver版本不兼容,或者提示CUDA unavailable。
原因通常是这样的:你的镜像里安装的PyTorch或CUDA Toolkit需要较高版本的GPU驱动,而新实例的GPU型号或驱动版本比原实例低。
排查步骤:
- 在新实例上执行
nvidia-smi,确认驱动版本。 - 确认当前PyTorch要求的最低驱动版本(如果PyTorch自带CUDA 12.x,一般需要驱动支持12.x)。
- 如果驱动版本过低,可以升级驱动,或者换一台GPU型号更新的实例。
这里要注意,GPU驱动一般不在镜像里,而是由平台根据GPU型号预装。所以即使你做镜像时的环境没问题,换到不同GPU型号的实例时,驱动可能有差异。一个稳妥的做法是:在公共镜像的基础上,使用一个兼容性较好的CUDA版本,比如CUDA 11.8,它在大多数驱动上都能运行。
另外,如果程序报libcudnn.so.8 not found之类的错误,说明cuDNN路径没对。用conda安装的cuDNN一般在/root/miniconda3/envs/train/lib/下,检查LD_LIBRARY_PATH是否包含这个路径。
5.3 大文件上传断线怎么办
上传大文件经常断线,这个痛点想必很多人都有过。处理思路很清晰:用支持断点续传的工具。
我推荐rsync。哪怕传到一半断了,重新执行同一条rsync命令,它会自动补齐剩余文件,从断点继续传,不用从头再来。
如果数据源在对象存储上,用wget加-c参数也能续传。如果是从本地大文件通过scp传,可以先把文件分块再传:
bash复制# 本地将一个10GB大文件拆成5个2GB的分块
split -b 2G big_file.tar big_file.tar.part_
# 传到服务器
scp -P 2222 big_file.tar.part_* root@8.xxx.xxx.xxx:/root/data/
# 到服务器合并回原文件
cat big_file.tar.part_* > big_file.tar
rm big_file.tar.part_*
这种方法的好处是,即使某个分块传失败,只补传那个分块就行,不需要重传整个文件。缺点是需要手动管理分块和合并,适合偶尔用一次的场景。
5.4 实例磁盘空间不足
实例磁盘空间不够,是另一个高频问题。我用的一招是du定位大目录:
bash复制du -sh /root/* /root/.cache /tmp 2>/dev/null | sort -hr | head -20
哪个目录占了几个G,一目了然。常见的空间杀手:
/root/.cache:pip和Hugging Face的缓存,经常会堆到好几个GB。/root/miniconda3/pkgs:conda安装包的缓存,conda clean -a -y能清掉大部分。/root/.local/share:某些应用的数据目录。/tmp:各种临时文件。
清理完这些,空间通常能释放不少。如果还是不够,可以把数据转移到数据盘,然后删除系统盘上的数据副本。不要一遇到空间不够就急着扩盘,很多时候是缓存冗余导致的问题,清理一下就能解决。
5.5 新实例无法正常启动或登录失败
制作好镜像后创建新实例,偶尔会遇到无法启动或无法登录的情况。可能的原因和排查步骤:
- 登录方式问题:有些镜像默认没有开启SSH密码登录,新实例的登录信息需要看控制台提供的密钥或一次性密码。如果之前实例依赖密钥登录,而镜像里没有把公钥配置好,新实例会登录不上。
- 防火墙或安全组问题:检查控制台的安全组规则,确认放行了SSH端口和业务端口。
- 系统配置损坏:比如改过
/etc/fstab或系统服务设置,导致新实例启动异常。这种情况只能回退到之前的可用镜像。
针对登录失败,我的建议是:制作镜像前,确认当前实例能通过密码或密钥正常登录,不要把登录配置改得太“个性化”。
6. 团队协作与成本控制经验
6.1 镜像命名与版本管理规范
团队里多个人共用GPU平台时,如果镜像命名混乱,找起来会非常痛苦。我见过有人保存镜像我直接叫“test”“final”,过了两天自己也分不清哪个是哪个。
推荐一个命名范式:
text复制框架-版本-CUDA版本-Python版本-备注-日期
示例:
text复制pytorch-2.3.0-cu121-py310-v1.2-20250115
tensorflow-2.12.0-cu118-py39-v1.0-20250116
描述里写清楚这个镜像装了哪些关键依赖、数据集路径、启动脚本路径。这样团队里任何人拿到镜像都能快速判断是否适合当前任务。
6.2 数据与镜像解耦:别把数据集塞进镜像
这条经验我反复提,因为太重要了。团队协作时,如果大家各自的镜像里都内置了同一份数据集,会产生几个问题:镜像体积快速膨胀、存储费用飙升、数据更新后每个镜像都要重新制作。
正确做法是:数据放数据盘或对象存储,镜像只负责环境。创建实例时,同时挂载数据盘或拉取数据。这样数据更新时,只需要更新数据一份,所有基于同一镜像的实例都能获取最新数据,不用反复制作镜像。
如果必须把数据放在实例本地,也建议只放缓存副本,并建立一套自动同步机制,从对象存储增量拉取最新数据。
6.3 不想一直开机时,如何保住“现场”
GPU是按时租用的,很多同学训练完不关实例,结果费用越积越高。但关了实例,环境和数据又怕丢失。怎么平衡?
我的做法是三层保障:
- 不需要长时间运行的临时环境,直接用镜像保存,然后释放实例。下次要用,从镜像创建新实例即可。
- 需要保留的大数据集,放数据盘。释放实例后数据盘保留,下次创建实例时挂载回来。
- 代码和配置,全部推送到Git仓库。这层保障最稳,不管实例和镜像怎么折腾,代码永远在。
这样即使某天误删了实例或镜像,损失也只限于环境配置,代码和数据都能快速恢复。我在智星云上一般训练完就把实例释放,只保留一个基础镜像,成本能省不少。
6.4 一点最终建议:把环境做成“声明式”更保险
镜像快照虽然方便,但它是一种“黑盒”式的保存方式——你知道环境能跑,但不知道具体是怎么配置的。这就有个隐患:如果某天平台出问题,镜像丢失或损坏,你可能连环境都找不回来。
所以我强烈建议,在镜像之外,同时维护一份“声明式”的环境配置:
requirements.txt或environment.yml:所有依赖包的精确版本。install.sh或init.sh:从零安装环境的一键脚本。- 项目文档:记录安装过程中手动处理过的特殊步骤,比如源码编译某个库、修改系统配置、设置环境变量等。
有了这套“声明式”配置,即使镜像丢失,你也能在20-30分钟内从公共镜像重建一个完整环境。这比依赖镜像快照更可靠,也更符合版本管理的思想。
在我实际的项目中,通常是这样配合的:日常开发迭代,直接基于镜像环境工作;每个里程碑阶段,更新镜像并同时更新requirements和启动脚本;关键节点,测试一次“从公共镜像+声明式配置重建环境”的流程,确保重建方案可行。
这套组合拳,让我在多个项目里都避免了“环境丢失导致重来”的噩梦。
最后再分享一个小体会:镜像和数据共享这些操作,看起来是“后勤工作”,不产生模型效果,但它们对效率的影响一直很直接。环境准备和数据搬运如果顺畅,你每天真正花在模型调试上的时间会多出很多;反过来,如果这些基础工作没有理顺,再多的GPU算力也填不满时间被浪费的坑。最好从第一次用GPU云平台开始,就培养“环境可重建、数据可复用”的习惯,后面会感谢这个决定的。
