Vast.ai 上手:搜机器、开实例、跑起第一个推理服务
第一次在 Vast.ai 上租机器的人,大概率会在两个地方栽跟头,而且两个都不是技术问题。
一个是磁盘。创建实例时那个存储滑块,官方文档写得很直白:实例创建以后磁盘分配就定死了,改不了。盘小了,跑到一半没空间,唯一的出路是重新开一台更大的、把数据搬过去。另一个是「停止」这两个字的含义。你以为点了 Stop 就不花钱了,实际上文档在三个不同页面反复提醒同一件事:停止只暂停 GPU 计费,存储照收,要彻底停掉所有费用只能销毁实例。
这两条都写在文档里,但都写在你不会第一时间点开的那一页。下面按真正的操作顺序走一遍,把这类「文档里有、但你踩到了才会去查」的点提前摆出来。如果你还不清楚这个平台跟传统云厂商的形态差别,可以先看这个平台本身是怎么一回事。
一、动手之前:两把钥匙和一个开关
前置条件其实只有三件,但缺任何一件你都会卡在「点了按钮没反应」的状态。
第一件是邮箱验证。文档明确写了:验证邮箱之前,你既不能租机器也不能建团队。注册后去收件箱(连垃圾邮件一起翻),验证链接点掉;没收到可以在设置页重发。这一步经常被跳过,因为注册流程走完看起来一切正常,直到你点 Rent。
第二件是余额。充值入口在 Billing 页,支持信用卡、BitPay 和 Crypto.com 几种方式,余额显示在控制台右上角。这里有个机制值得你提前想清楚:余额归零时,正在跑的实例会自动停止——注意是停止,不是销毁。把这条和「停止不停存储费」放在一起看,就知道为什么文档要推荐两个保险:一是开自动充值(只支持信用卡),把自动扣款的触发线设在高于你日均消耗的水平;二是把低余额邮件提醒设在比自动扣款线再低一点的位置,这样万一扣款失败你还能收到通知。只开自动充值不开提醒,扣款一失败你是毫无察觉的。
第三件是连接方式的钥匙,这个要在开实例之前准备好,不是开完再补。走 SSH 就先在本地生成密钥对,把公钥上传到 Keys 页面。走 Jupyter 就要装官方提供的浏览器证书(文档页面上把它写成 TSL certificate,说的就是 TLS 证书)。证书这事在不同系统上后果不一样:Windows 和 Linux 上不装只是每次都弹「您的连接不是私密连接」,点高级再继续还能进去;macOS 上浏览器会直接拦死,不把证书装进钥匙串并设为信任就连不上。装一次就永久没有警告了,所以值得在开机器之前花两分钟做完。
二、模板决定了你后面所有的麻烦
模板(Template)这个词听起来像「预设配置」,但按文档给的定义,它更准确的说法是一层 docker run 的包装:镜像、环境变量、要暴露的端口、on-start 命令、磁盘默认值、provisioning 脚本,全在模板里。你启动实例是「从一个模板启动」,所以模板选错,后面每一步都在跟它较劲。
官方自带的推荐模板建在 vastai/base-image 和 vastai/pytorch 上,里面已经带了 Instance Portal、基于 Caddy 的 TLS 和认证。这三样如果你自己配,够折腾一晚上,所以第一次上手没有特别理由就别急着上自定义镜像。
模板里最容易被忽略、又最容易出怪问题的是启动模式(launch mode)。文档给的是三种:Entrypoint、SSH、Jupyter。关键差别在于——SSH 和 Jupyter 这两种模式会把初始化脚本注入你的镜像,你镜像原本的 entrypoint 会被替换掉。也就是说,如果你自己的镜像靠 entrypoint 脚本做初始化,选了 SSH 模式之后那段逻辑根本不会跑,通常要把它挪进 onstart 脚本。文档还给了一条很实在的经验:自定义镜像在 SSH 或 Jupyter 模式下遇到看不懂的加载错误时,改用更简单的 Entrypoint 模式,自己把 SSH 或 Jupyter 装起来。
同一个坑还有环境变量的版本。用 -e 设的变量对 onstart 脚本是可见的,但在 SSH、tmux、Jupyter 会话里默认看不到。要让它们在交互会话里也能取到,得在 onstart 里把它们写进 /etc/environment:
env >> /etc/environment;
官方发布的镜像在自己的 entrypoint 里已经做了这件事,所以你只在自定义镜像上会撞到。另外账号设置页里可以设一批环境变量,它们会自动注入你启动的每一个容器——放 API key 之类的东西比每次手填靠谱。
三、搜索页:卡片上哪几项真的影响决策
搜索页左边和顶部是一堆筛选条件(地区、GPU 型号与数量、硬件规格、租用参数),中间是一行行 offer 卡片。要先明白 offer 是什么:它是某个 host 愿意出租的一份具体配置,你点 Rent 就是和这个 host 就当前条款建立一份租用合同;这份 offer 在结束或被 host 下架之前,对其他人仍然是可见可租的。
卡片上的字段很多,有几项是真影响决策的:
- 机器分级。文档分三档:Unverified 是没被平台测过的新机器,默认就被过滤掉不显示;Verified 是通过了内部测试的;Secure Cloud(Datacenter)是在符合平台数据中心标准的机房里、有蓝色标签,文档直接推荐生产环境用这一档。你要跑正式服务,这一栏比 GPU 型号更该先看。
- Max Duration,最大租期。这是合同能持续的上限,不是「租到什么时候」的建议值。
- Reliability Score,机器历史在线率和健康度的度量,新机器都从同一个起点起步、随表现往上爬。文档提了一句判断原则:你租得越久,这个分数越重要。短跑一次不必过分纠结,长期跑就得挑。
- DLPerf,平台自定义的深度学习性能分。它的用处是让不同 GPU 的 offer 能横着比,而不是让你去比裸参数。
- 网络带宽与端口数。带宽是上下行 Mbps,端口那一栏是这台机器潜在可用的端口数量。如果你要对外暴露服务,这两栏必须看。
- 磁盘类型、速度和可用总量,以及价格。价格是 GPU 租金加上你已分配存储的那部分,鼠标悬停在价格上会展开明细,带宽的价格也在那里看。
还有一个容易读错的细节:卡片上所有规格显示的都是「这份 offer 分到的份额」,不是整机。CPU 核数和系统 RAM 会写成「分配给本 offer 的 / 整机总量」的形式,别把分母当成你能用的量。
实例类型也在这一步决定。文档分三种:on-demand 是固定价、高优先级,在最大租期内有保障;reserved 是长期承诺换预付折扣;interruptible 走竞价,最便宜,但被别人出价超过、或者 on-demand 需求突然上来时可能被暂停。第一次跑不要选 interruptible——你还分不清「服务挂了」和「被抢占了」的区别。
磁盘滑块在这一页,它既是筛选条件也是参数输入。文档给的原则很简单:宁可多给一点。理由除了创建后改不了,还有一条——停机状态下存储照样按分配量收费,所以「多给」也不是没有代价,得估一个真实的量。要估的话,显存和磁盘占用怎么算这篇能给你一个下限;GPU 型号怎么挑那篇则能帮你把筛选条件收窄,别在搜索页里一个个卡片看。
四、开起来之后怎么连上去
点 Rent 之后实例进入启动流程。快慢取决于镜像:机器上已经有缓存的镜像起得很快,需要新拉的可能要等很久,网络慢加镜像大甚至能拖到一小时以上。这里有一条对新手很友好的规则——文档明确说了,实例处于 Loading 状态时不计费。所以等镜像,等的是时间不是钱。
状态按钮本身就是文档里的一套状态机,值得记一下:Creating 是平台在创建,Loading 是在下载镜像,Connecting 是 Docker 已经跑起来但连接还没验证通过,Open 表示可以从浏览器进去,Connect 表示点开看 SSH 信息,Inactive 是已停止但数据还在,Scheduling 是正在尝试重启、等 GPU,Offline 是机器和平台断了联系。其中 Connecting 卡住的诊断和其他几种不一样:文档说这通常意味着端口配置坏了,建议报告这台机器并换一台,而不是继续等。
三种连接方式的适用场合,按文档的描述分工是清楚的:
SSH 适合你要在命令行里干活——装依赖、跑脚本、开推理服务进程、用 tmux 挂着长任务。前提是公钥已经上传。
Jupyter 适合交互式试探:加载模型看看能不能跑、算算显存够不够、调 prompt。代价是那张证书,以及 JUPYTER_SERVER_ROOT 限定了 Jupyter 能看到的根目录,上面的目录你在界面里进不去。
Instance Portal 是官方推荐模板里自带的那层,用来访问实例里跑着的 Web 服务。它带了 Caddy 的 TLS 和认证,这一点对开了公网端口的服务很重要——一个裸的 HTTP 推理端口暴露在公网 IP 上,等于谁都能调。
五、端口映射:新手真正卡住的一步
这一节是第一次跑起服务最容易折在里面的地方,原因是它不符合直觉。
文档说得很清楚:实例有完整的外网访问能力,但通常没有独立的公网 IP。公网 IP 是机器上多个实例共享的,所以你的每一个开放内部端口,都会被映射到这个共享 IP 上一个随机的外部端口。也就是说,服务在容器里监听 8081,从外面访问的绝不是 ip:8081。
端口从两个来源被打开:镜像里的 EXPOSE 指令会自动变成端口请求;此外你可以在 docker 选项里用 -p 加:
-p 8081:8081 -p 8082:8082/udp
这些是在 EXPOSE 和默认端口(SSH 的 22、Jupyter 的 8080)之外额外开的。文档也说了单实例的开放端口总数有上限,不是想开多少开多少。
实例加载完之后,从实例面板打开 IP Port Info 弹窗查真实映射,格式是 PUBLIC_IP -> INTERNAL_PORT,文档给的例子是这样:
65.130.162.74:33526 -> 8081/tcp
意思是 65.130.162.74:33526 通向容器内 8081 上跑的任何东西。同一个映射在容器里也有对应的环境变量可以读,命名规则是 VAST_TCP_PORT_<内部端口>,比如 VAST_TCP_PORT_22 是映射到 22 的外部端口,UDP 对应 VAST_UDP_PORT_X。写启动脚本时要拼自己的外部访问地址,就靠这个变量,别硬编码。
如果你的程序非要求外部端口和内部端口一致(比如某些分布式通信场景),文档给了 identity ports 这个机制:用 70000 以上的越界端口号请求,比如 -p 70000:70000,映射出来的外部端口是随机的、但内外一致,具体值从 $VAST_TCP_PORT_70000 读。
验证映射通不通,文档给的办法最省事——在实例里起一个最小的 HTTP 服务,然后从浏览器访问对应的外部地址,看到目录列表就说明通了:
python -m http.server 8081
这条建议的价值在于把问题一分为二。先确认「端口映射对不对」,再去排查「我的推理服务本身有没有起来」。不然你面对一个连不上的地址,根本不知道该怪网络还是怪模型。
服务真跑起来之后还有一个收尾动作:让控制台上的 Open 按钮指到你的服务端口,用 OPEN_BUTTON_PORT 这个环境变量指定内部端口(文档给的例子是 -e OPEN_BUTTON_PORT=7860)。同理 JUPYTER_PORT 改 Jupyter 按钮指向的内部端口,JUPYTER_TOKEN 设访问用的 token。这几个变量不影响服务能不能跑,但影响你每次进控制台是点一下就进去,还是得翻端口表。
至于推理服务本身怎么起、参数怎么配,Vast 的这几页文档管的是容器和网络,不管你容器里跑什么。具体到把模型 serve 起来那一段,可以看推理引擎的部署和常见参数。另外这里有个反直觉但很硬的限制:实例本身就是 Docker 容器,文档说 Docker-in-Docker 不支持,所以你那套 docker compose 编排的部署方式在这里直接不能用,得改成在容器里直接起进程。
六、start / stop / destroy 分别动了什么
这是最该在第一天就搞清楚的一组语义,因为它同时牵着你的数据和你的账单。
先记住计费口径:实例按秒计费它「运行」的时间,加上按存在时间计的存储费。两个计时器是分开的。
Stop(方块图标)暂停实例,数据保留,GPU 计费停止,存储费继续。文档在存储页面把这条又强调了一遍,还补了个更不舒服的细节:停机状态的存储费率可能比运行时还高。所以「先停着,回头再说」这个习惯在这个平台上是会持续出血的。
Destroy(垃圾桶图标)永久删除实例和它的全部数据,这是唯一能让存储费归零的操作。销毁之前先把要留的东西弄出来:控制台有 Copy Data 在你自己的实例之间传,有 Cloud Sync 同步到云存储(文档提醒 Cloud Sync 只在带 Secure 标识的可信数据中心用),也可以走 SCP/SFTP 拉回本地。destroy 掉的实例连查看都查不到了,只有模板历史会留着给你复用配置。
Restart(播放图标,停止状态下才出现)尝试把 GPU 抢回来。这里要理解一个前提:停止的实例没有 GPU 预留,GPU 是独占资源、从不在用户之间共享。所以重启时实例进入 SCHEDULING 状态排队等卡,如果这张卡已经被别人租走、或者被高优先级任务占住,你可能一直等不到。文档给的判断是:卡住一会儿还没动,基本就是卡被别人拿了,再点一次停止可以取消排队,考虑把数据拷到新实例上。换句话说,停机并不保留你的 GPU,只保留你的数据——这和大部分公有云的停机语义不一样,也是这套市场模式的直接后果。
还有两个时间点会咬人。一个是合同过期:过期的实例不能再启动,而且过了文档规定的保留期就会被清掉,所以租期快到时要主动去取数据。另一个是前面说的余额归零自动停机——停机不停存储费,如果你既不充值也不销毁,账就一直在走。
顺便说存储的另一种形态:卷(Volume)能在实例销毁后继续存在、还能重新挂到新实例上,但它有硬限制——卷绑在创建它的那台物理机上,不能跨机器迁移,只能挂给同一台宿主上的实例,而且要删卷得先销毁挂着它的实例。所以卷解决的是「同一台机器上反复开关实例」的持久化,不解决「换机器」的问题。跨机器要保命的东西,还是走 Cloud Sync 或者拉回本地。
七、第一次用,把风险控制在哪儿
这几页文档读下来,有一件事它没直接说、但字缝里全是:这是个市场,不是一家云厂商。硬件是别人的。文档自己写得很老实——host 在技术上能访问自己机器上的文件,敏感数据要用 verified 的数据中心并且自己做加密;平台在搜索页的问答里也直说「我们只是市场,不管理也不提供硬件,没有货我们也没办法」。这个定位决定了你该怎么控制第一次的风险。
具体建议是四条。第一次就只跑能重来的东西,不要把唯一一份数据放上去;有生产意味的服务优先挑 Secure Cloud 那一档,别为了便宜去碰 Unverified 和 interruptible;磁盘按你估算的上限给,因为它改不了;以及最重要的——跑完之后不要停,要销毁,数据先导出。停机留着的那份「方便」,成本是持续的存储费加上一张随时会被别人租走的卡。
还有一层判断得你自己量:这套东西的操作面比托管 API 大得多。密钥、证书、端口映射、启动模式、磁盘估算、销毁前导数据,每一项都是你的活。如果你的用量还没到那个量级,这些活的时间成本可能比省下来的钱更贵——这笔账怎么算,自建推理还是直接调 API 那篇讲得更细。另外有些细节官方文档确实没写清,比如不同宿主的存储费率差异具体怎么算、停机费率高多少,文档只给了「可能更高」这种定性表述,真实数字以你在控制台悬停价格看到的明细为准——开机之前把那个明细展开看一眼,比读完所有文档都管用。
算完账发现自建推理不划算?
先用托管端点把业务跑起来,量上来了再回头算自建的平衡点。