1. 先把账算清楚:个人项目走到租显卡这一步的真实原因
第一次接触云显卡租赁的人,多半是被一张本地跑不动的模型逼过来的。本地机器上一张入门级显卡,显存八个G,跑个推理勉强够用,一旦开始微调或者训练,CUDA out of memory就像闹钟一样准时出现。这时候摆在面前的选择其实只有两个:要么花一笔钱把卡换掉,要么按小时租一张远程的卡来用。我见过不少人凭直觉选了前者,结果买回来的卡三个月后就比同价位的新卡落后一档,而项目早就结束了。
这篇文章讲的就是后一条路——按小时计费的云端显卡租用平台,从注册、登录到真正把卡租出来跑起来的完整流程。下面我会用"A 平台"来代指这一类提供 GPU 实例按小时计费服务的平台,因为不同厂商的界面虽然长得不一样,但底层逻辑高度一致:账号体系、实例规格、镜像、存储、计费规则这几块积木是不变的。把这几块搞明白,换到任何一家平台都能在十分钟内上手。
适合谁看:手里只有笔记本或者消费级显卡、需要临时跑训练或推理的算法同学;需要复现别人论文结果但硬件不够的在校学生;偶尔要做一次批量推理、不值得为它买卡的工程人员。如果你已经是常年管理集群的人,这篇可能对你偏基础,但里面关于计费和持久化的几个坑,我猜你也踩过。
在动手注册之前,先花五分钟把成本模型想清楚,这一步省下来的钱比后面任何省钱技巧都多。自购一张中高端显卡,除了卡本身的支出,还要算上电源升级、机箱散热、整机待机功耗、以及最重要的——折旧速度。一张卡在两年内贬值过半是常态,而你真正满载运行它的时间可能只有几百小时。租卡的本质是把这笔固定成本拆成可变成本:用多少付多少,不用就不付。如果你的 GPU 使用时长一年累计低于一千小时,租基本都比买划算,这还没算上省掉的折腾时间。
1.1 自购显卡的隐性成本与租用的盈亏平衡点
很多人算账时只算了显卡单价除以使用天数,得出"买更便宜"的结论,但漏掉了三块成本。第一块是配套成本:一张功耗三百瓦以上的卡,往往要换电源、加机箱风扇,某些型号还需要转接供电,整机噪音和发热也会影响你日常使用。第二块是时间成本:驱动版本、CUDA 版本、框架版本三者之间的兼容问题,能吃掉一个新手整整两天,而租用平台的镜像里这些通常已经配好了。第三块是机会成本:你为了省钱买了一张刚好够用的卡,半年后项目变复杂了,卡又不够用,等于白买。
盈亏平衡点可以粗略地这样估:以一张中端卡为例,整机投入按一万二算,两年折旧按六成计,实际沉没成本约七千二;同样这两年如果租卡,按每小时两块五、累计用满一千小时计,是两千五。差距非常明显。只有当你的使用强度接近"每天满载八小时以上、持续一年"这种程度,自购的边际成本才会追平。所以我的建议很直接:项目周期在三个月以内、或者使用是间歇性的,一律先租。等确定这个方向要长期做下去,再考虑自建。
另外一个容易被忽略的点是:租卡让你有条件"按任务选卡"。做数据预处理和模型调试只需要很小的卡,做正式训练才需要大卡,同一周内你可能在三种规格之间来回切换,这是自购做不到的。这种灵活性本身就是价值。
1.2 按小时计费的成本模型里,哪些时间在悄悄烧钱
按量计费的计费单位是"实例运行时长",理解这一点是后面所有省钱操作的前提。实例处于运行中状态时,不管你是在跑训练、在调代码,还是只是开着窗口发呆,甚至浏览器关掉了但实例没关,都在计费。很多人第一次用,晚上十点开着实例试了一下,困了直接合上电脑睡觉,第二天醒来发现扣了十几个小时的钱,这种事故非常普遍。
所以正确的心理模型是:开机 = 打开计费开关,关机 = 关闭计费开关。中间所有的操作都要围绕这个开关来做。平台一般还会提供"无卡模式"这类只保留 CPU 和存储、不占用显卡的低价状态,用于传数据、装环境、改代码,价格通常是正常计费的十分之一左右。这是整个流程里最值得养成习惯的一个动作,后面第五章会详细讲怎么把它用出效果。
还有一项隐形成本是存储。实例关机后,系统盘和数据盘通常还会继续占用并产生少量费用,具体规则各家不同。如果你的项目数据是几十上百 G,长期挂在那儿也是一笔钱。养成项目结束就清理实例、把重要产物打包下载回本地的习惯,比什么优惠券都实在。
2. 注册环节远不止填个手机号:账号体系与额度限制
进入注册页面后,你会看到手机号、邮箱、密码这几个基本字段。看起来毫无技术含量,但这里有几个决定你后续体验的细节。首先是账号唯一性:多数平台一个手机号只能注册一个账号,且注册后实名信息与账号绑定,意味着你不能用同一个身份开多个小号去领新人优惠。其次,平台通常会对新账号做额度限制,比如单次开机不得超过若干小时、总消费有上限,或者某些大卡型号对未实名账号不可见。这些限制不是刁难,而是风控手段,但对急着跑实验的人来说会造成困扰——你可能看教程说某型号好用,自己界面上却找不到,原因往往就是账号等级不够。
注册时填的邮箱建议用长期可用的工作邮箱,不要用临时邮箱。后续的账单、实例异常通知、发票申请都走这个邮箱,而且部分平台支持邮箱登录作为手机号登录的补充。密码方面,不要图省事用你其他站点的常用密码,因为这个账号关联着你的实名信息和可能的余额,一旦泄露损失比普通论坛账号大得多。
2.1 实名认证前后的权限差异与新手配额
实名认证这一步在不同平台的叫法不一样,有的叫身份核验,有的叫资质认证,本质都是把你的账号从"匿名"提升到"可信"。完成之后的直接变化通常有三点:可用实例规格变多、单次开机时长上限放宽、可以申请发票。没有完成认证时,你可能只能开小规格实例,或者每次开机限时很短,跑长任务会被强制中断。
从实际操作经验看,认证最好在注册当天就做完,不要等开到一半发现规格受限再回来补。核验流程一般需要上传证件照片并做人脸比对,耗时几分钟到几小时不等,部分时段需要人工审核。如果赶上你要赶一个 deadline,这个等待时间会很要命。我见过有同学凌晨两点想开大卡,结果卡在审核上,硬生生等到第二天中午。
提示:不同平台对同一身份可持有的账号数量有明确上限,不要尝试用家人身份批量注册来薅新人券。这类操作一旦被风控识别,可能导致账号被限制,反而耽误正事。
新人配额这块,平台一般会送一些代金券或者体验时长,有的还提供特定型号的免费试用。这些券通常有有效期和适用型号限制,不是所有卡都能用。领之前先看一眼使用条件,别等券过期了才发现。我个人的做法是:把新人券留着不用在调试环节,而是留到正式跑长任务的那一次,因为调试环节用无卡模式基本花不了几个钱。
2.2 账号安全设置的几个必做项
注册完成登录后,第一件事不是去租卡,而是把安全设置过一遍。至少要做三件事:开启二次验证(如果有)、设置独立的支付密码或消费限额、检查登录设备记录。二次验证通常支持手机验证码或验证器应用,后者更可靠一些,因为不依赖短信通道。
消费限额这个功能很多人不知道,但它能救命。设置一个每日或单次消费上限后,即使你忘了关机,损失也有天花板。我给自己设的上限大致是"一次完整实验的预算乘以一点五",这样正常使用完全不受影响,异常情况会自动拦住。
还有一点是关于账号共享。团队里为了省事共用一个账号的情况很常见,但这会带来两个问题:一是密钥和实例互相干扰,别人关机把你的训练停了;二是账单无法拆分,谁用了多少说不清。如果确实需要多人协作,优先看平台是否支持子账号或者团队空间,把权限和计费分开。没有这个功能的,至少约定好实例命名规则和关机责任人。
3. 登录之后的头等大事:密钥、凭证与连接方式
登录进去看到控制台,界面上密密麻麻一堆入口,很容易让人手忙脚乱。我的建议是先不要急着点"租用",而是把连接方式这一块搞清楚,因为它决定了你后面怎么把代码送上去、怎么把结果拿下来。云上实例的连接方式主要有三种:网页端的集成开发环境、SSH 命令行、以及本地编辑器远程连接。这三种底层是同一套东西,只是入口不同。
网页端集成环境最省事,打开浏览器就能写代码、跑 notebook,适合快速验证想法。缺点是长时间操作体验一般,大文件上传下载不方便,而且它本质上是把实例暴露在一个网页端口上,安全性依赖平台的实现。SSH 命令行最灵活,适合跑长任务、用tmux挂后台。本地编辑器远程连接则介于两者之间,写代码的体验最好,适合做正式开发。
3.1 SSH 密钥对的生成与粘贴,以及为什么不推荐密码登录
密码登录云实例在技术上可行,但强烈不推荐。原因很实际:公网暴露的 SSH 端口每天都会被大量自动化脚本扫描爆破,密码再复杂也架不住长期暴露,而且密码登录没法做免密自动化。密钥登录则是一次配置、长期省心。
生成密钥对的命令在任何 Linux 或 macOS 终端里都能跑,Windows 上用 Git Bash 或 WSL 也一样:
ssh-keygen -t ed25519 -C "gpu-work" -f ~/.ssh/gpu_work这里选ed25519而不是默认的rsa,是因为它在同等安全强度下密钥更短、握手更快,现代平台基本都支持。-f指定文件名,避免覆盖你已有的默认密钥。执行后会生成两个文件:gpu_work是私钥,绝对不能外传;gpu_work.pub是公钥,就是要粘贴到平台里的那一串。
cat ~/.ssh/gpu_work.pub复制输出的整行内容,包括开头的ssh-ed25519和结尾的注释,粘贴到平台的密钥管理页面。粘贴后平台一般会显示密钥指纹,用来核对是否完整。最容易出错的地方是复制时漏掉换行或者多带了空格,导致密钥格式校验失败。如果平台报"密钥格式不正确",先检查是不是复制时把终端提示符也带进去了。
配置好之后,本地需要写一个~/.ssh/config片段,把私钥和主机对应起来:
Host gpu-box HostName <平台给出的连接地址> Port <平台给出的端口> User root IdentityFile ~/.ssh/gpu_work ServerAliveInterval 30ServerAliveInterval这行看着不起眼,但很重要。长时间训练时如果本地网络抖动,没有心跳的 SSH 连接会被中间设备掐断,你回来发现终端死了,虽然训练进程可能还在跑(如果在tmux里),但看不到输出会很难受。加上心跳能显著降低断连概率。
3.2 网页端凭证、API Token 与它们各自的风险面
除了 SSH 密钥,平台通常还会给你两类凭证:网页登录态和 API Token。API Token 用于命令行工具或者脚本调用,比如批量开关机、查询余额、自动提交任务。这类 Token 的权限往往很大,能操作你账号下的所有实例。
管理 Token 的原则很简单:一个用途一个 Token,能设过期时间就设,不用了就删。我曾经图省事把所有脚本共用一个永不过期的 Token,后来某次把脚本传到公共仓库时忘了清理,虽然没有造成实际损失,但事后想想相当后怕。现在我的做法是:本地脚本用的 Token 设三十天有效期,到期重新生成;临时调试用的 Token 用完立刻删除。
注意:不要把任何凭证硬编码在 notebook 或者代码里,尤其是打算分享出去的代码。用环境变量或者本地配置文件,并在
.gitignore里排除配置文件,这是最基本的一道防线。
4. 租赁界面上的每个选项,究竟在决定什么
现在进入正题。租赁页面看起来选择很多,其实可以归成四组决策:在哪租(区域)、租什么(卡型与规格)、租多久(计费模式)、装什么(镜像)。这四组决策互相影响,顺序上建议先定区域和卡型,再定计费模式,最后选镜像。
先说一个总的原则:不要追求"最强配置",要追求"刚好够用且最便宜"。新手最常见的浪费是,明明只是跑个推理 demo,却租了最高端的卡,一小时的钱够跑一整天小卡。反过来也有反例,用显存不够的卡硬跑大模型,反复 OOM 重试,浪费的时间比省下的钱多得多。
4.1 区域选择与资源余量之间的关系
区域选择通常被当作无关紧要的一项,实际上它影响两件事:延迟和有没有卡。延迟方面,选离你物理位置近的节点,SSH 敲命令的回显会顺畅很多,传文件也快。如果你在国内,选国内节点;如果只是挂后台跑训练不交互,延迟的影响就很小。
更关键的是余量。热门卡型的热门区域经常"无卡",尤其是晚上和周末,很多人抱着"先开机占着"的心态,导致资源紧张。这时候有几个应对办法:一是错峰,把调试和传数据放在白天,晚上再开大卡跑训练;二是换区域,同一卡型在不同区域的余量差异可能很大,多刷几次往往能捡到;三是关注平台的"可预约"功能(如果有),提前锁定资源。
还有一个实用技巧:关机释放后不要立刻重新开机,而是先看一眼当前余量,确认有卡再操作。我踩过的坑是,关机去改配置,结果改完发现卡被抢光了,只能等半天。现在我的流程是:需要改配置时,先在无卡模式里改好、把环境装好、镜像保存好,最后一次开机直接跑。
4.2 卡型对比:显存、算力与互联带宽哪个更要紧
选卡的时候,参数表上最显眼的是算力数字,但对个人项目来说,显存往往才是第一约束。举几个典型场景:跑一个七十亿参数的模型做推理,用半精度加载,光权重就要十几个 G,加上激活值和 KV cache,二十 G 以下的卡基本不够;做小模型的全量微调,显存需求大约是参数的十几倍;做 LoRA 这种参数高效微调,需求会低很多,中等显存的卡就能胜任。
下面这张表是我按常见任务类型整理的选卡思路,具体型号每年都在变,但判断维度是稳定的:
| 任务类型 | 首要约束 | 建议显存区间 | 备注 |
|---|---|---|---|
| 数据预处理、小模型调试 | 几乎无 | 8G 以下 | 用无卡模式或最小规格足够 |
| 中等规模模型推理 | 显存 | 16G - 24G | 注意 batch size 与序列长度 |
| 参数高效微调 | 显存 | 24G - 48G | batch size 可以适当放大 |
| 全量微调、多卡训练 | 显存 + 互联带宽 | 48G 以上 | 多卡时卡间带宽影响明显 |
| 大模型推理部署 | 显存 + 显存带宽 | 按模型规模定 | 带宽影响首 token 延迟 |
关于互联带宽,只有在你确实要用多卡时才需要关心。单卡任务里,卡间互联速度完全不影响你。很多人被"多卡高速互联"的宣传带偏,花高价租多卡实例,结果代码根本没做分布式,只用了其中一张卡,纯属浪费。
还有一个参数是显存带宽,它在推理场景下的影响比算力更大。同样算力的两张卡,带宽高的那张在自回归生成时吞吐会明显更好。判断方法很朴素:如果你的任务是逐 token 生成,优先看带宽;如果是大批量矩阵运算,优先看算力和显存容量。
4.3 计费模式的选择:按量、包周期与无卡状态
计费模式基本分三档:按量计费(按小时或按分钟)、包日包周(有折扣但需要预付)、以及前面提到的无卡状态。选择逻辑取决于你的使用模式。
按量计费适合绝大多数个人场景,因为它最灵活,随时可以释放。包周期适合确定要连续跑几天的大任务,折扣通常在七到八折,但风险是一旦中途不需要了,钱退不回来。我的经验是:只有当你确定未来三天内实例都不会闲置超过一半时间时,包周期才划算,否则按量更省。
无卡状态是整个省钱体系的核心,需要单独说清楚。它的一般形态是:实例保留,磁盘数据都在,环境配置都在,但显卡被释放,计费降到很低的水平。适合做这些事:整理代码、装依赖、下载模型权重、把结果打包上传、写报告。唯一不能做的就是跑 GPU 计算。
实际操作中我把工作流拆成两段:无卡模式里准备,有卡模式里执行。准备阶段包括拉代码、装pip包、下载数据集、跑通一个极小的样例确认代码没 bug。执行阶段开机、跑训练、保存结果、立刻关机。这样一张卡真正被占用的时间可能只有计划的一半,费用也差不多减半。
5. 一次完整开机:从选镜像到跑通第一个脚本
前面的选择都定好之后,点"创建实例"到能跑代码,中间还有几步。这几步的配置错误率最高,而且很多错误是不可逆的(比如系统盘写满导致环境损坏),所以值得逐项确认。
创建流程一般是:选镜像 → 选系统盘大小 → 挂数据盘 → 配置端口 → 确认下单。顺序可能略有不同,但要素是一致的。
5.1 镜像选择的分岔口:框架镜像还是纯净系统
镜像决定了你开机后的初始环境。平台提供的镜像大致分三类:基础系统镜像(干净的 Linux,什么都没有)、框架预装镜像(已经装好 CUDA、PyTorch 或 TensorFlow 的特定版本)、自定义镜像(你自己保存的环境快照)。
新手强烈建议直接用框架预装镜像,省掉最痛苦的环境配置环节。选的时候注意两个匹配:框架版本与你的代码匹配,CUDA 版本与框架版本匹配。比如你的代码用了某个较新的 API,就得选对应版本的框架;如果代码里有编译扩展,CUDA 版本还必须和编译时一致,否则会报一些很难懂的符号错误。
纯净系统镜像适合两类人:一是对环境有完全掌控需求的老手,二是需要装一些预装镜像里没有的特殊依赖。用纯净镜像的话,装 CUDA 驱动、配conda、装框架这一套走下来,顺利的话半小时,不顺利的话半天。我个人的做法是:先用预装镜像跑通,再把自己的额外依赖固化成启动脚本,这样每次开机只需跑一遍脚本,几分钟就恢复环境。
#!/bin/bash # 开机后执行的初始化脚本,放在数据盘里,每次复用 set -e pip install --no-cache-dir -r /data/workspace/requirements.txt -i <镜像源地址> export PYTHONPATH=/data/workspace:$PYTHONPATH echo "env ready"这里特意把requirements.txt和脚本都放在数据盘,因为系统盘的内容在某些操作下可能丢失,数据盘相对更持久。
5.2 数据盘与系统盘:哪些东西会丢,哪些不会
这是新手最容易吃亏的地方,必须讲透。云实例的存储一般分两类:系统盘和数据盘(有的平台叫本地盘、临时盘、网盘等)。它们的持久性规则完全不同。
系统盘存放操作系统和默认的软件环境。它的行为取决于平台实现:有的平台在实例释放后系统盘一并删除,有的会保留但额外计费。更麻烦的是,即使实例不释放,系统盘容量也通常很小(几十 G),而模型权重、数据集动辄几十上百 G,很容易写满。系统盘写满的后果很严重:日志写不进去、进程被杀、甚至环境损坏。我见过训练跑到第七个小时因为磁盘满而崩溃的,那种心情很难形容。
数据盘的容量通常可以单独指定,价格比系统盘低,且挂载路径固定。行业里常见的挂载点有/root/xxx-tmp、/data、/mnt/xxx这几种,具体以平台文档为准。判断标准很简单:凡是希望关机后还在的东西,一律放数据盘。代码、数据集、模型权重、训练日志、保存的 checkpoint,全部指向数据盘路径。
| 存放内容 | 建议位置 | 原因 |
|---|---|---|
| 代码仓库 | 数据盘 | 需要长期保留、反复使用 |
| 数据集与预训练权重 | 数据盘 | 体积大,系统盘装不下 |
| 训练日志与 checkpoint | 数据盘 | 崩溃后需要回溯 |
conda环境 | 系统盘 | 可重建,重建成本可接受 |
| 临时脚本、调试 notebook | 数据盘 | 顺手,避免忘记 |
还有一个细节:很多库默认往用户主目录写缓存,比如 HuggingFace 的模型缓存默认在~/.cache。如果你不修改这个路径,下载的模型全在系统盘里,几次就满了。修改方式通常是设置环境变量:
export HF_HOME=/data/cache/huggingface export TRANSFORMERS_CACHE=/data/cache/huggingface export TORCH_HOME=/data/cache/torch把这三行写进~/.bashrc或者开机脚本,能省掉后面很多麻烦。
5.3 端口映射与从本地连上去的完整链路
实例开起来之后,平台会给你连接信息:一个主机地址(可能是域名也可能是 IP)、一个 SSH 端口、以及网页端入口。这里要注意,平台分配的端口通常不是默认的 22,而是映射出来的高位端口,所以本地连接时必须显式指定。
如果你要跑一些 Web 服务,比如 TensorBoard、Gradio 界面、或者自建的 API,还需要把服务端口映射出去。主流平台的做法是提供一个自定义端口的功能,你把服务监听在指定端口上,平台通过反向代理对外暴露一个地址。这里有两个常见坑:
第一个坑是服务必须监听在0.0.0.0而不是127.0.0.1。默认很多框架只监听本地回环,这种情况下即使端口映射配对了,外面也访问不到。启动命令里加--host 0.0.0.0或者等价参数即可。
第二个坑是端口冲突。同一台机器上可能有平台自己的服务占着常用端口,你选了 8080 结果起不来。解决办法是换一个不常用的高位端口,比如 16000 以上,或者在启动前用ss -lntp看一眼占用情况。
# 检查端口占用 ss -lntp | grep -E ':(8080|6006|7860)' # 启动一个 Gradio 演示,监听所有网卡 python app.py --host 0.0.0.0 --port 16006至于本地编辑器远程连接,思路是让它通过 SSH 跳板连上去,配置里填上前面~/.ssh/config定义的那个 Host 名就行。连接成功后,在编辑器里打开数据盘上的项目目录,就能像本地开发一样改代码、开终端、跑调试。这套组合用熟之后,云端实例和本地机器在使用体验上的差别会变得很小。
6. 真正烧钱的地方在关机前后:持久化与省钱组合拳
写到这里,租卡的流程其实已经跑通了。但根据我的观察,新手和熟手之间最大的差距不在会不会开机,而在关机前后那几分钟的处理。同样一个实验,熟手的实际计费时长可能只有新手的一半,差别全在这里。
核心逻辑就一句话:显卡只用来做非它不可的事。所有能提前做的、能延后做的、能用 CPU 做的,都挪到无卡状态里。下面是我现在固定使用的一套流程,可以直接抄。
6.1 开机前、运行中、关机后的三段式操作清单
开机前(无卡模式):拉代码、装依赖、下载数据集和权重、跑通一个最小样例(比如只跑十步训练)、确认数据路径和输出路径写的是数据盘。这一阶段的目标是让真正开机后的第一秒钟就在做有效计算。
运行中(有卡模式):启动训练命令,务必用tmux或nohup挂后台,避免 SSH 断连导致进程被杀。定期把 checkpoint 存到数据盘。用watch -n 5 nvidia-smi监控显存和利用率,如果发现 GPU 利用率长期低于三成,说明瓶颈在数据加载或者 CPU,这时候继续开着卡纯属浪费,应该停下来优化DataLoader的num_workers和预取参数。
关机后:把关键产物打包下载,或者保存成自定义镜像。清理数据盘里的中间文件。确认实例已关机(不是仅仅关掉网页)。
这一套里最容易被跳过的就是第一步的"跑通最小样例"。很多人觉得反正代码在本地跑过,直接上云跑全量,结果开了卡之后才发现路径错了、依赖缺了,卡在那儿调试,一小时就这么烧掉了。宁可多花十分钟用无卡模式验证,也不要省这十分钟。
6.2 镜像保存与环境复现:把配环境这件事做一次就好
如果你打算长期做这个项目,反复配环境是最没效率的事。平台的"保存镜像"功能就是为此设计的:把一个已经配好的实例状态打包成镜像,下次开机直接从这个镜像启动,环境原封不动。
使用时有几个注意点。第一,镜像有大小限制,不要把一个塞了上百 G 数据的实例拿去保存,会失败或者非常慢。正确做法是镜像里只保留环境和代码,数据放数据盘。第二,保存镜像本身要花时间和少量存储费,但它能省下的调试时间远超这点成本。第三,保存前先清理缓存和临时文件,pip cache purge、删掉__pycache__、清掉日志,能让镜像小很多。
更轻量的替代方案是把环境固化成脚本(前面那个init.sh)。优点是体积小、可版本控制、换平台也能用;缺点是重建需要几分钟。我的做法是两个都用:日常迭代用脚本,确定要长期挂着的项目保存一个镜像做兜底。
6.3 数据上下行的省时做法
数据上传下载是最耗时间也最容易被忽视的环节。几十 G 的数据集,用网页上传可能要几个小时,中间断一次还得重来。几个实用做法:
优先用命令行传输工具,支持断点续传。小文件多的时候先打包成tar再传,能极大减少开销,因为单个小文件的传输开销远大于文件本身。
# 打包,排除缓存和日志 tar -czf dataset.tar.gz --exclude='*.log' --exclude='__pycache__' ./dataset # 断点续传上传(假设平台提供对象存储或直连方式) rsync -avP --partial dataset.tar.gz gpu-box:/data/workspace/rsync的-P等价于--progress --partial,中断后重跑会从断点继续。如果是超大文件,也可以考虑分卷压缩再传,失败时只需重传某个分卷。
下载结果时同理,把零散的 checkpoint 打包成一个文件再拉,比一个个拉快得多。还有个小技巧:如果结果只是一些指标和图表,能在实例里生成好图片再下载图片,比下载原始日志回本地分析更省事。
7. 踩过的坑,以及每一步的排查链路
下面这几个问题我都真实遇到过,排查过程写出来,比直接给答案有用。
7.1 实例创建失败:先分清是资源问题还是配置问题
创建失败时,平台给的提示往往很模糊,比如"创建失败,请重试"。这时候要分两层排查。
第一层是资源层:该区域该卡型当前是否还有余量。判断方法很直接,换一个区域或者换一个相近的卡型再试,如果能成功,那就是余量问题,跟你的配置无关。这种情况不要死磕,换区最快。
第二层是配置层:镜像与卡型是否兼容、系统盘是否小于镜像要求、数据盘挂载路径是否合法、账号是否有权限使用该规格。排查看报错里有没有提到具体的资源名称,如果有,基本就是配置问题。常见的一类是选了过高规格的实例但账号未完成认证,报错会拐弯抹角地说"无权限",实际原因在账号等级。
还有一种情况是"创建成功但一直启动中",超过十分钟还起不来。这通常是镜像拉取慢或者节点异常,处理办法是删掉重建,不要一直等。
7.2 训练跑到一半进程消失:OOM 还是被系统杀掉
进程无声无息消失是最让人抓狂的情况。排查顺序建议是:先看显存,再看内存,最后看磁盘。
看显存:如果日志在崩溃前有CUDA out of memory,那就是显存不够。注意显存不够不一定是模型太大,也可能是 batch size 太大、序列长度太长,或者你忘了torch.no_grad()导致推理时也在建计算图。解决办法按代价从低到高:减小 batch、开梯度累积、开混合精度、开梯度检查点、换更大的卡。
看内存:这里说的是主机内存,不是显存。如果进程是被系统 OOM killer 干掉的,系统日志里会有记录:
dmesg -T | grep -i -E 'killed process|out of memory'有这行说明是主机内存不够,通常是DataLoader的num_workers开太大、或者一次性把大数据集读进了内存。把num_workers降到 CPU 核数的一半以下,用流式加载代替全量加载。
看磁盘:没有任何报错、进程直接没了,也可能是磁盘写满导致写入失败。开机后先df -h看一眼挂载点使用率,数据盘和系统盘都要看。如果系统盘到了百分之九十五以上,赶紧清理,把缓存目录改到数据盘。
7.3 连不上、打不开、卡在握手:网络问题的分层定位
连接类问题建议按这个顺序排查,每一步都能排除掉一大片可能性。
第一步,确认实例状态。实例是不是还在运行?有没有因为余额不足被停机?这一条最基础但最容易忘,我至少有两次折腾半天,最后发现是实例早就欠费停了。
第二步,确认地址和端口。平台给的主机地址和端口,每次开机可能会变。如果你用的是自己写的~/.ssh/config,记得同步更新。很多人连不上是因为还在用上一次的旧地址。
第三步,确认密钥。报Permission denied (publickey)时,检查本地私钥权限是不是过宽(chmod 600是必须的),检查平台里的公钥是否完整。还有一个隐蔽的坑:如果你本地有多个密钥,SSH 可能会按顺序尝试并触发服务器的最大尝试次数限制,解决办法是在 config 里显式指定IdentitiesOnly yes。
第四步,确认服务端监听。网页端的服务打不开时,先在实例里用curl http://127.0.0.1:<端口>自测。本地能通、外面不通,就是端口映射或监听地址的问题;本地也不通,就是服务根本没起来。这一步能把问题范围砍掉一半。
我在实际操作中体会最深的一点是:别急着改配置,先确定问题在哪一层。关掉实例重开、换密钥、重装环境,这些操作看起来都很"彻底",但在没定位清楚的情况下做,往往只是把问题掩盖掉,下次换个形式再来一遍。分层排查慢一点,但一次就能解决,而且下次遇到类似问题,你能在五分钟内判断出方向。
最后分享一个小习惯:每次开机后第一件事,跑一条nvidia-smi && df -h && free -g,把卡型、显存、磁盘余量、内存余量一次性看清楚,存到项目的 README 里。下次换卡或者复现结果时,这些环境信息能帮你省掉很多"为什么我这里跑不出这个结果"的困惑。