
上周有个机房值班的同事问我一件怪事。同一排 8 台机器、64 张卡,白天调度群里全是等卡的消息,有的任务说三天没排上。晚上十点他去机房转了一圈,一半机器的风扇已经降下来了,监控上显存几乎空着。
白天不够用、晚上一半闲,这两件事发生在同一批卡上,前后差不到十二个小时。他导出调度记录给我看,白天的等卡列表排了两页,夜里十一点的利用率曲线几乎贴着地面。他问我,是不是卡买少了。
我去翻了一遍任务记录才发现,排队的是训练,闲着的是推理。这是两种活,不是一种活多了、一种活少了。
一句话原理
同一张卡,训练像把一本练习册从头算到尾、中途不能停笔;推理像柜台答问,来一个人答一句,答完就等下一个。
训练要的是长时间不被打断、显存(卡上自带的内存)装得下整份作业;推理要的是答得快,人多了能加卡、人少了能退卡。
这两种要求长在同一张卡上,很难同时满足。所以白天排队和晚上空转,其实是同一件事的两面。
一个具体例子
拿共享厨房来比。灶台就是 GPU,一道炖菜是训练,快餐档口是推理。
炖菜要占三个灶、连着炖三周,中途掀锅就前功尽弃。快餐档口只在中午那两个小时排队,下午基本没人。
假设一个机房有 64 张卡。训练任务占 32 张,连跑 3 周,中途不许被切走。推理白天高峰要 24 张,夜里只要 6 张。
如果训练池和推理池各自划死,推理那 32 张卡里有 26 张从夜里十点闲到早上八点。卡时就是一小时占一张卡,算账用的单位。一晚空掉 26 × 10 = 260 卡时,一个月约 7800 卡时。
按一张卡一小时 10 元算(假设价),一个月空转掉七万八。这钱谁也没收到,但租金照付。
以上数字都是假设,只为把账算清,不代表任何真实机房。
一个小闭环

- 现场。 输入是一张卡一张卡的显存占用、任务起止时间。动作是从调度器和卡上监控各取一份。输出是谁在跑、谁在等。
- 连上。 输入是每个任务能不能被打断、最长要连着跑多久。动作是给任务打上“可抢占”或“独占”的标记。输出是一张能混着排的任务表。少了这步,训练被当成推理切走,一晚上白跑。
- 算清。 输入是两类任务每个时段用了几张卡。动作是按时段对一遍“该用几卡、实际几卡”。输出是空转的卡时数。少了这步,不知道该挪多少卡。
- 做动作。 输入是这张空转清单。动作是把批量推理、离线评测这类能被打断的活,塞进训练的空档;推理按时段伸缩。输出是同一批卡干更多活。少了这步,空转就一直空转。
- 证明结果。 输入是动作前后的利用率(卡真正在算的时间占多少)、等卡时长、推理延迟。动作是对比同一个时段。输出是省下多少卡时、训练有没有被拖慢。少了这步,说不清是省了还是乱了。
三条技术确认点
一、训练断了要退多远。 现场要确认多久存一次检查点、恢复要几分钟。这决定了它能不能和别人共用一台机器。
二、推理慢到几秒算超时。 用户点下去到看见开头那个字,几秒算超时、超了怎么排队,要落在纸面上。没有这条线,共享卡跑推理就是赌。
三、显存按峰值留还是按均值留。 训练的显存按模型大小基本固定,推理的显存随同时在线的人数往上爬。留错了,白天高峰一到就爆。
常见误区
看起来是卡买少了,其实是卡不能被切。训练要整卡独占好几周,推理要随时加随时减,两种活挤在一个池子里就互相堵。
看起来是推理更省钱,其实是推理的高峰最贵。白天那几个小时要的卡,和训练整月占的卡是同一批,账单上却分成两笔。
看起来是混着跑一定划算,其实是混错了更贵。抢先把训练打回上一个检查点,重跑掉的卡时比省下的还多。
回到开头
那位同事的机房不是卡少了,是两种活被塞进了两个互不相通的池子。训练这边排不上队,推理那边夜里空一半。
一个慢,是因为它必须一次算完、中途不能停;一个要快,是因为它在等人来问,答慢了人就走。
把能被打断的活填进空档,把不能断的活留足整卡,同一批卡就能多干一截活。空转掉的那部分卡时,本来就是钱。
算力:慧知开源智算调度平台
GPU 资源池化、任务调度、多租户和计费一套管,装在自己服务器上,能改能扩。
点这里看详情 →