一、先问一个问题:你的算力是真不够,还是被浪费了?

做AI落地的团队几乎都在喊"卡不够",但把监控拉出来看,情况往往相反。

一个典型场景:一张40GB显存的GPU,上面只跑了一个ASR(语音识别)模型,实际占用约10GB,剩下30GB闲置;计算利用率长期在5%~10%之间徘徊。

问题出在调度粒度上。在传统Kubernetes集群里,GPU是按整卡分配的:

resources:
  limits:
    nvidia.com/gpu: 1   # 申请1,就独占一整张物理卡

调度器无法理解"我只要10GB显存、30%算力"这种诉求。你申请1,它就绑定一整张卡,哪怕你只用得到四分之一。

结果就是:显存浪费约75%,算力浪费约95%。传统整卡分配模式下,GPU集群整体利用率普遍低于25%。

更麻烦的是扩容。流量高峰来了要扩,但扩的单位是"整机"“整卡”。为了应对偶发的峰值,只能长期保持高配节点,平时大量闲置——扩容慢、配置重、成本失控。

“算力不够用"和"算力被浪费”,是同一件事的两面。


二、思路:把GPU拆开用

核心改动只有一句话:把"整卡独占"变成"按需切分"。

基于Kubernetes构建调度层,通过GPU虚拟化技术,对显存和算力做一体化精细调度——按显存大小和算力占比动态切分,用多少切多少。

一张40GB的卡,可以这样分:

切片模型显存分配
切片1Chat10GB
切片2Embedding8GB
切片3Rerank12GB
切片4ASR10GB

同一张卡内多模型并行、互不干扰。

以NVIDIA MIG(Multi-Instance GPU)为例,可以在硬件层面把物理卡切成多个实例:

# 开启 MIG 模式
nvidia-smi -i 0 -mig 1

# 查看可用的实例规格
nvidia-smi mig -lgip

# 创建 GPU 实例(以 1g.10gb 规格为例)
nvidia-smi mig -cgi 19,19,19 -C

# 确认切分结果
nvidia-smi -L

切分完成后,Pod 就能申请到具体规格的切片,而不是整卡:

resources:
  limits:
    nvidia.com/mig-1g.10gb: 1   # 只要一个10GB切片

效果:原来5个模型(Chat / Embedding / Rerank / ASR / TTS)至少要5张卡,现在按实际显存需求切分,2张卡就能装下。资源利用率提升2~3倍。

一个14B的模型可能只需要H100约35%的容量,一个ASR或TTS模型只要10GB——把这些碎片拼起来,硬件采购量能显著下降。


三、进阶:跨节点算力聚合

单机切分只解决了一半问题。集群里往往是这样的:Node A有张空闲的24GB卡,Node B有张48GB在跑任务,Node C三张80GB全空着。

如果调度范围局限在单机,这些碎片依然用不起来。

所以第二步是跨节点算力资源聚合——把集群内不同机器、不同型号的空闲GPU,统一感知、聚合成一个共享算力池:

  • 无论是24GB的3090、48GB的A40,还是80GB的H100
  • 无论插在哪台物理机上
  • 调度器统一纳管,按当前负载、显存余量、算力空闲度,动态选择最优节点和卡型

这带来一个思维转变:扩容不是"加机器",而是"加资源"。

实测一个36张卡的异构集群,聚合后可用算力约2.1 PFLOPS,整体利用率可以做到78%左右——相比传统模式的不足25%,是三倍的差距。


四、高可用:扩了还得稳

扩容只是手段,服务不掉才是目的。这块有三个关键设计:

1. 自动扩缩容

实时监控GPU使用率、QPS、P95延迟,流量上升自动扩容、回落自动缩容,全程无需人工介入。

# HPA 示例:基于自定义指标(QPS)自动扩缩
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
spec:
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Pods
      pods:
        metric:
          name: inference_qps
        target:
          type: AverageValue
          averageValue: "3000"

2. 故障迁移与秒级恢复

异常实例自动隔离,请求无感迁移到健康实例;故障实例秒级重建,服务持续在线。相比传统方案分钟级的恢复时间,这是量级差异。

3. 硬件级隔离

这一点在多租户场景下尤其关键。MIG提供的是硬件级隔离——每个切片有独立的显存和计算资源边界。

意味着:同一张卡上,切片3的实验模型OOM崩了,切片1、2、4上的生产推理服务完全不受影响。

这就是为什么可以放心地把生产环境、开发测试、不同团队的负载部署在同一批GPU上——既省卡,又不用担心互相拖累。


五、和"节点级扩容"的本质区别

市面上很多平台也说支持扩容,但粒度停留在节点级:资源不够了就加节点、加机器。

对比一下:

维度传统节点级扩容显存级动态扩容
扩容粒度按整机/整卡MB级精细切分
单卡利用率低(常低于25%)高(可达78%)
GPU切分方式静态分区动态切分 + 硬件级隔离
跨机调度调度范围有限统一算力池,全局调度
故障恢复分钟级秒级迁移

差别在于:一个是在原方案上打补丁,一个是把扩容粒度从"节点"细化到"显存分片"、把调度维度从"整卡"扩展到"跨卡聚合"。


六、落地建议

如果你的团队正在被GPU利用率低、扩容成本高、多模型部署难困扰,可以按这个顺序验证:

  1. 先测基线:用 nvidia-smi 或 DCGM 采集一周的显存占用和计算利用率,算出真实利用率——多数团队会被这个数字吓一跳

    # 每秒采集一次 GPU 显存和算力利用率,输出到 CSV
    nvidia-smi --query-gpu=timestamp,index,name,memory.used,memory.total,utilization.gpu \
      --format=csv,noheader,nounits \
      -l 1 >> gpu_baseline.csv
    

    如果有 DCGM,用 dcgmi dmon 可以拿到更细粒度的 SM 利用率和显存带宽,比 nvidia-smi 更准:

    dcgmi dmon -e 203,204,1004,1005 -d 1000
    # 203: GPU利用率  204: 显存利用率  1004: 显存用量  1005: 显存总量
    
  2. 挑一个场景试点:选显存需求小、并发不高的模型(ASR/TTS/Embedding 这类)先做切分,风险低、见效快

  3. 再做跨节点聚合:单机验证通过后,再把调度范围扩到整个集群

  4. 最后上自动扩缩和隔离策略:生产、开发混部前,务必先验证隔离效果

GPU 很贵,别让它闲着。同样的硬件,跑更多模型、撑更高并发,这件事的技术路径已经比较清晰了,剩下的是工程落地问题。


本文数据来自实际 K8s + NVIDIA GPU 集群的监控记录。欢迎在评论区交流你们集群的利用率数据和踩坑经验。

更多推荐