第一次用超算中心的人,十个里有八个会在命令行里犯嘀咕:我在这敲敲打打,算力卡是不是已经在偷偷烧我的配额了?为什么敲个nvidia-smi还提示找不到显卡,是不是我压根就不该进来,得赶紧退出?这问题听着基础,但确实卡住了不少人——尤其是从本地实验室搬过来的同学,习惯了在自己机器上随便跑,一到国家超算中心这种共享环境,连呼吸都怕扣费。
先说结论:在登录节点和计算节点上敲命令行,几乎不会消耗算力卡资源,而“找不到显卡”多半也不是你的问题,是你站错了地方、或者看错了时机。但“要不要退出”这件事,确实分情况,不能一概而论。这篇文章我把超算中心里命令行、算力卡和“找显卡”这件事从头到尾捋一遍,读完你就知道什么时候该慌,什么时候该安心干活。
1. 先分清你站在哪台机器上:登录节点不等于计算节点
1.1 登录节点和计算节点到底有什么区别
国家超算中心的集群,物理上是一大片机器堆在一起,但逻辑上严格分成两类角色:登录节点和计算节点。这两者的分工完全不一样。
登录节点(有的地方叫前端机、提交机),是你通过 SSH 连上去的第一台机器。它的主要职责是让你做几件事:编辑代码、编译程序、管理文件、提交作业、查看作业状态。说白了,它是一个“前台”,给你一个相对稳定的环境做准备工作。绝大多数超算中心的登录节点,都不挂 GPU/加速卡,或者只挂极少量的调试卡。因为登录节点是大家共享的,如果每个人都上去跑 GPU 计算,那调度系统就形同虚设了,整个集群都会卡死。
计算节点是真正跑活儿的地方。你通过作业调度系统提交任务之后,调度器会从资源池里挑一台符合你申请条件的计算节点,把 CPU、内存、GPU 这些资源划给你,然后你的任务就在那台机器上跑。这个过程通常是隔离的——你自己的作业不会跑到别人的计算节点上,别人也占用不了你申请到的资源。
所以,当你在登录节点上敲nvidia-smi发现“No devices were found”或者“Command not found”,这太正常了,不是你的账号出问题了,而是这台机器本来就没有给你分配显卡。你站在前台,当然看不到后厨的灶台。
1.2 算力卡从来不是“常驻”在命令行里的
很多第一次用超算的人默认了一个模型:登录到集群之后,整个集群的资源都是透明的,我能看到所有显卡,所有内存,所有核数。实际上完全不是这样。
超算中心为了保证公平调度,会把资源“藏起来”。你在登录节点上执行nvidia-smi,看到的只是登录节点这一台机器的情况。哪怕这个集群里有几百张 A100,只要这些卡没有通过作业调度系统分配给你的某个作业,你在登录节点上就看不到它们。这就像你去酒店开房,前台能看到整个酒店的房态(其实你也看不到),但你没有拿到房卡之前,是进不了任何一间房间的。就算你走到某一间房门口,门锁也是开的,你也用不了里面的设施。
命令行里的“能找到资源”和“能用资源”是两码事。超算环境里,只有当你提交了作业、作业开始运行,你才“拿到房卡”。这时候你进入计算节点,才能看到真实的 GPU 状态。
2. 命令行敲命令,到底会不会消耗算力卡
2.1 算力卡只有在操作系统分配给你之后才存在
关于“命令行会不会消耗算力卡”,先要理解算力卡在超算中心是如何被使用的。
算力卡,也就是 GPU/加速卡(NVIDIA A100、H800、华为昇腾、寒武纪等),在超算中心里不是像 CPU 那样时时刻刻都在被调度的。GPU 是稀缺资源,通常按“张”来申请。你通过 Slurm(或 PBS 等调度系统)提交一个作业,在脚本里写--gres=gpu:1,意思是“请给我分配 1 张 GPU 卡”。调度器会找到一台有空闲 GPU 的计算节点,把这张卡绑定到你的作业上。从这一刻起,这张卡在这个作业的运行期间内,基本是“你的”。
那么,你在命令行里敲ls、cd、vim、grep这些操作,消耗的是什么?是 CPU、内存和一点点硬盘 I/O。这些操作发生在你的登录会话或者作业的控制进程里,根本不会去碰 GPU 的计算单元。GPU 需要被“用”起来,通常是通过 CUDA 之类的运行时库,由你的程序代码在计算时去调用。
换句话说,敲命令这个行为本身,几乎不会消耗算力卡。真正消耗算力卡的,是你的程序里跑起来的张量运算、模型推理、训练循环。命令行只是一个“遥控器”,它不占灶台,只有你真正开火做饭才烧燃气。
2.2 真正“扣钱”的指标是什么?卡时、核时和排队时间
超算中心的计费方式通常有两种:核时(CPU 核数 × 运行小时数)和卡时(GPU 卡数 × 运行小时数)。不同的中心计费粒度不一样,但共同点是:计费按你申请的作业资源算,而不是按你“敲了多少命令”算。
举个例子:你写了一个脚本,申请了 1 张 A100、8 个 CPU 核,计划跑 10 个小时。调度器把资源分配给你之后,不管你这 10 个小时里是在真正跑训练,还是在命令行里发呆调 bug,这 1 张卡 × 10 小时的“卡时”都会从你的账户里扣除。有些超算中心还允许你在作业排队期间占用资源但不计算(比如运行前检查阶段不计费),但绝大多数情况下,作业一启动,计时就开始了。
所以,在命令行里敲敲nvidia-smi、看看日志、改改参数,这些操作本身不额外计算卡时。但如果你的作业申请了 GPU,你却让它空转——比如把训练脚本写成无限循环等待,或者挂起了一个交互式 session 却一直不干活——那这些时间照样计费。这才是你最需要心疼的地方。
提示:很多超算中心提供“调试队列”或者“短作业队列”,资源申请时间短(比如 1 小时),计费单价也更便宜。专门用来做命令行调试、查 GPU 状态、跑小规模测试,非常划算。正式跑大任务之前,先在调试队列把环境跑通,能省下不少正式队列的卡时。
2.3 哪些命令会碰 GPU,哪些绝对不会
为了彻底打消你“敲命令会不会烧卡”的焦虑,我列一个实际经验中的分类清单:
绝对不碰 GPU 的命令:
ls、cd、cat、grep、find这类文件操作vim、emacs、less这类文本编辑查看git版本管理操作python启动一个什么都没干的解释器(只要不 import 深度学习库并执行张量运算)squeue、sinfo、scontrol这类调度系统查询命令
会碰 GPU 的命令 / 场景:
- 在 Python 里执行
torch.cuda.is_available()并运行tensor.cuda()或模型.fit()之类的操作 - 直接调用
nvidia-smi本身——但要注意,nvidia-smi只是读取 GPU 状态,它不会让你产生真正的“算力消耗”,只是让驱动汇报一下温度、显存占用、利用率。偶尔敲几下完全没问题,不用因此退出 - 运行任何基于 CUDA/OpenCL 的推理或训练程序
所以,你在命令行里正常地「查看显卡状态」这个动作,无论是nvidia-smi还是rocm-smi,都只是在“看仪表盘”,没有烧油。
3. “找不到显卡”的三种典型情况:你可能只是虚惊一场
接下来重点聊聊最让人焦虑的场景:明明觉得自己申请了 GPU,却在命令行里死活看不到显卡。以我的经验,90% 的情况是下面这三种之一。
3.1 情况一:你在登录节点上直接敲了nvidia-smi
前面说过,登录节点大概率不带显卡。你 SSH 登录后的默认位置就是登录节点。在这个节点上,nvidia-smi的输出要么是特别简短的“No devices were found”,要么直接报错Command not found(因为登录节点上可能根本没装 NVIDIA 驱动,或者驱动只装了核心部分)。
判断方法:敲hostname,看看返回的主机名是不是带有login、front字样。如果是,基本可以确定你在登录节点上。此时找不到显卡,不是你的问题,是常规状态。
正确处理:不用退出,也不用慌。你需要通过调度系统申请一个带 GPU 的计算节点,然后进入那个节点才能看到显卡。后面的第 4 节会给你具体的命令。
3.2 情况二:你申请了 GPU,但交互式任务没有正确加载
很多超算中心支持交互式作业:你敲一条srun或salloc命令,调度系统直接给你开一个登录到计算节点的 shell。很多同学在这里踩坑——他们确实申请了 GPU,但参数写错了或者漏了,导致实际分配的计算节点根本没有挂 GPU。
举例:有的集群默认分区叫gpu,有的叫gpu2,有的集群--gres的值不是gpu:1而是按型号写A100:1或者a800:1。如果你把分区名写错,调度器可能在你不注意的时候给你分配了一个 CPU 节点;如果你把--gres写错,调度器可能会直接报错拒绝你的任务。
更隐蔽的情况是:调度器分配的计算节点上有多张 GPU,但你的交互式任务进入节点时,没有自动设置CUDA_VISIBLE_DEVICES环境变量,导致你看到的 GPU 列表为空,或者只看到一部分。Slurm 在部分配置下会帮你设置这个变量,但不同数据中心环境差异很大。
判断方法:进入计算节点后,先执行echo $CUDA_VISIBLE_DEVICES。如果输出为空,再执行nvidia-smi -L(列出所有 GPU)对比。如果nvidia-smi -L能看到 GPU 但 CUDA 程序说找不到设备,多半是环境变量的问题。
3.3 情况三:你的计算节点是异构节点,但任务被分配到无 GPU 的机器
超算中心为了提升资源利用率,计算节点往往不是清一色的。有的节点有 GPU,有的没有,还有的节点上有多种型号的 GPU。你申请了 GPU 资源,但调度器可能把任务分到了一个没有 GPU 的节点——这通常发生在你的申请参数不够严格、调度器做了“变通”的情况下。
这种状态特别气人:squeue里明明显示你的作业在运行(状态 R),你进入计算节点却发现nvidia-smi什么都看不到。这时候不要急着退出,先用scontrol show job <作业ID>查看你的作业实际占用了哪几个节点、申请了哪些资源。
如果确认作业没有绑定到带 GPU 的节点,正确做法是取消作业重新提交,而不是在节点上继续耗时间。重新提交时把分区名、--gres参数写清楚,最好再加一个--constraint参数(例如--constraint=A100)来强制指定 GPU 型号,调度器就不会乱分配了。
4. 要不要退出?先把这几条命令跑一遍再决定
“是否退出”是很多用户最纠结的地方。退出怕浪费排到的资源,不退出又担心白白烧卡时。实际上,你可以用几条命令快速搞清楚自己现在的状态,然后做出正确决策。
4.1 先看自己在哪台机器上
进入命令行后,第一件事永远是hostname。如果返回的名称包含login、front之类的字样,说明你在登录节点,此时没有任何算力卡资源挂在你的会话上,你也没有占用任何计算资源,谈不上“需不需要退出”——你可以继续在登录节点上编辑代码、提交作业,这都是安全的。
如果返回的名称是node、cn、gpu之类的字样,说明你已经在计算节点上了。那么继续看下一步。
4.2 查看你的作业被分配了什么资源
使用squeue -u $USER可以列出你当前所有的作业,记下你关心的那个作业 ID,然后执行:
scontrol show job <作业ID>输出里重点看这几行:
JobState:是RUNNING还是PENDINGNodeList:你实际跑在哪个节点Gres:这一行列出了作业申请的 GPU 类型和数量,例如Gres=gpu:A100:1(意思是申请了一张 A100)NumCPUs/MinMemoryNode:CPU 和内存的分配情况
如果JobState是PENDING(排队中),那你的资源还没有分配,此时你敲任何命令都不会消耗卡时,等到排到之后会开始计费。如果JobState是RUNNING,但Gres显示的申请数量是 0 或者没有 GPU 相关字段,说明这次提交的作业本来就没申请 GPU。你可以考虑是否是提交脚本写错了。
4.3 交互式 GPU 任务的正确打开方式
如果你想要的是“一个能敲命令、能看到显卡、能在里面跑模型的交互式环境”,正确姿势是:
srun --partition=gpu --gres=gpu:1 --ntasks=1 --cpus-per-task=4 --pty bash各参数含义:
--partition=gpu:指定 GPU 分区,具体的分区名以超算中心的使用手册为准,有的是gpu,有的是gpu2、gpu_a100,不要照抄--gres=gpu:1:申请一张 GPU 卡--ntasks=1:只启动一个任务--cpus-per-task=4:额外申请 4 个 CPU 核,避免模型预处理时 CPU 资源不够--pty bash:分配一个交互式终端
执行成功后,你会“挪”到计算节点上,此时再敲nvidia-smi就能看到你申请的卡了。用完之后,直接exit退出这个交互式 session,资源会立即释放,计费也会停止。这种交互式 session 用完一定要退出,不然它会一直挂着,把你排队排来的卡时白白烧掉。
4.4 什么时候“退出”才是正确的操作
整理一下,遇到以下情况,退出是正确的:
- 你的交互式作业已经调完 bug,不再需要继续占着 GPU
- 你发现提交的作业参数写错了,GPU 没有申请到,正在空跑一个不完整的任务
- 你在计算节点上发现环境完全不对,需要回到登录节点重新配置
遇到以下情况,不必退出:
- 你在登录节点上,它本身不消耗算力卡
- 你的批处理作业已经在正常运行,你退出 SSH 也不会影响它(后台作业由调度系统托管)
这里要特别提一点:批处理作业不会因为你退出 SSH 就停止。你提交的脚本通过 Slurm 在计算节点上运行,跟你的登录会话完全解耦。很多人担心“我关了电脑、断了 SSH,作业会不会中断”——不会,超算中心的设计就是为了让你可以提交完任务就安心睡觉。但交互式 srun 不一样,你的终端退出了,进程也就断了。
5. 超算中心 GPU 使用的常见误区与实战经验
最后这部分聊几个我这些年见过的用户共性问题,也算给大家提个醒。
5.1 误区一:申请了 GPU 就必须“立刻看到”显卡
超算环境里有排队这一说。你提交了作业,不代表立刻就有资源给你。尤其到了晚上或月末,GPU 队列经常要排几个小时甚至一两天。在PENDING状态下,你即使在命令行里敲一万遍nvidia-smi,也看不到任何卡——因为资源还没分配给你呢。
正确做法是:提交作业后,用squeue -u $USER看状态,如果长时间PENDING且REASON列显示Resources或Priority,说明在等资源。这时候你不需要“退出”任何东西,该干嘛干嘛,等作业跑起来之后去计算节点查看即可。
5.2 误区二:以为 GPU 越贵越好,拼命申请大卡
国家超算中心的算力卡按型号分价格不同,A100/H800 这类顶级卡通常更贵,配额消耗也更快。很多新手一上来就申请 A100 跑一个小到用 CPU 都能秒完的任务,结果白白烧掉大量配额,还让后面排队的人等更久。
我的建议是:先在小卡上把代码跑通,再提交到大卡上跑完整训练。超算中心一般都有多种 GPU 分区,先用那种配额便宜、排队短的卡做测试,再转换到正式卡上。跑模型之前先用一行命令:
python -c "import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))"确认 CUDA 环境和显卡能对上,再启动正式训练脚本。这一步 5 秒钟,能省下你数小时的踩坑时间。
5.3 经验:命令行里查看 GPU 状态,别只知道nvidia-smi
nvidia-smi是 NVIDIA GPU 最基本的查看命令,但超算中心不一定全是 NVIDIA 的卡。比如有的中心部署了 AMD 的 Instinct 系列(用rocm-smi查看)或者国产昇腾、寒武纪、海光 DCU(各自有专门的工具,如npu-smi、dcu-smi等)。到了一个新环境,不确定用什么命令时,可以先看看有没有对应的工具:
rocm-smi:AMD 卡npu-smi info:昇腾卡dcu-smi:海光 DCUixsmi:燧原等国产卡
另外,还有一些交互式监控工具,比如nvtop,它像 Linux 的top一样实时刷新 GPU 利用率和显存占用,调试模型时非常好用。如果你的超算环境里没有预装,可以让管理员帮忙装一下,或者用pip install nvitop装一个轻量级的。
5.4 “找不到显卡”时,最后的大招:找管理员
上面说的排查方法都试过之后,还是找不到显卡,最不丢人的做法是直接问管理员。超算中心的支撑团队一般都很快响应。你只要把squeue -u $USER和scontrol show job <作业ID>的输出贴给他们,他们一眼就能看出问题出在参数还是节点配置。比你自己在命令行里反复试更强。
我见过最离谱的一次,是一个用户申请 GPU 的时候把--gres拼成了--gpu,调度器默默接受了这个错误参数(有些旧版 Slurm 不校验),给他分配了一个纯 CPU 节点,结果他在上面干瞪眼半小时。后来支撑团队看了一眼作业配置,三秒钟就指出了问题。所以遇到“找不到显卡”又不确定原因时,请务必留下作业 ID,这是你排查所有问题的基础。
5.5 命令行本身不“烧卡”,但别让调试占用你的卡时
最后成体系地强调一下核心观点:命令行操作本身几乎不消耗算力卡资源,但“卡时”的消耗与你的作业是否运行、是否占用了资源有关。你真正该关心的不是“敲命令会不会扣配额”,而是“我的作业有没有在正确高效地跑”。
如果你用交互式 srun 申请了 GPU 用来调试,调试完之后记得立刻exit释放资源。出一个有意思的细节:很多超算中心的调度策略是“先进先出 + 优先级抢占”,你长时间占着一个交互式 session 不退出,不仅烧自己的配额,还可能把后面焦急等着跑实验的同学急到跺脚。用超算的基本素养,就是「资源用完就还」。
我个人现在的习惯是这样:写代码、改脚本、看文档,全在登录节点做,每做一步只跑最小验证;真正需要 GPU 的时候,用srun开一个交互式任务,验证完马上退出;确认没问题,再写正式批处理脚本提交到队列。全程下来,命令行几乎没有额外消耗过卡时,排队时间也省了不少。