最佳实践
在资源估算、运行模式、隔离、优先级和灰度上线这几方面,工作负载注解的各个选项该怎么选
本页帮你决定选哪个注解选项,以及为什么。可以直接复制的清单见注解使用场景,准确的类型和默认值见注解参考。TFLOPS、VRAM 等术语见术语解释。
资源估算
1. 算力和显存都写上 request 和 limit
request 是调度器预留的量,决定一张卡上能放多少个 Pod;limit 是 Pod 被限制住的上限。request 按平稳负载写,limit 按峰值写。
tensor-fusion.ai/tflops-request: "10"
tensor-fusion.ai/tflops-limit: "20"
tensor-fusion.ai/vram-request: "4Gi"
tensor-fusion.ai/vram-limit: "4Gi"只写 limit 时,request 取相同的值。这样是安全的,但会一直按峰值预留。
2. 在线服务的显存 request 等于 limit
没用完的算力可以让给别的 Pod,之后再拿回来。显存不行:进程一旦占住就不会释放。所以显存 limit 高于 request,意味着卡满的时候 Pod 可能申请不到多出来的那部分显存。只有可以重试的任务才留这个差值。
3. 优先用 TFLOPS,少用百分比
compute-percent-* 写起来方便,但 T4 的 30% 和 A100 的 30% 相差很大,而且百分比不计入 namespace 的 GPU 配额。池里有多种 GPU 型号,或者依赖配额时,一律用 TFLOPS。两种写法不要用在同一个工作负载上。
4. 改用分片后,删掉原生 GPU limit
resources.limits 里残留的 nvidia.com/gpu: 1 仍然会影响请求。没写 gpu-count 时,GPU 数量由它决定;没有任何 tflops-* 注解时,它还会让请求变成整卡 100% 的算力。工作负载改用 TFLOPS 和显存注解之后,删掉原生 limit,并显式写上 gpu-count。
5. 先实测,再交给自动扩缩容维护
按实际运行的数据估算,不要照着模型卡片估。没法测量时,先写大一点,再加上 tensor-fusion.ai/autoscale: "true"。想先看自动扩缩容会怎么调、暂时不让它动手,可以用一个 autoSetResources.enable: true 但不写 targetResource 的 WorkloadProfile,这时推荐值只出现在工作负载的 status 里。见配置自动扩缩容。
运行模式与隔离
6. 没有特殊需要就用本地模式
本地 GPU 模式是池的默认值,到显卡的路径也最短。业务必须留在 CPU 节点上,或者 GPU 节点紧张到放不下业务 Pod 本身时,才选远程 vGPU 模式(is-local-gpu: "false")。需要在多个集群之间共用的清单,请显式写出模式,因为默认值取决于各自的池。
7. 按对“邻居”的信任程度选隔离模式
| 情况 | 模式 |
|---|---|
| 同一个团队的工作负载共用显卡 | soft(默认) |
| 租户之间需要更严格的性能隔离 | hard |
| 训练任务,或任何需要独占显卡的场景 | shared |
| 必须使用 MIG 这类硬件分区 | partitioned,并且集群已为此配置 |
有两点需要提前考虑:
hard的限额在 Pod 启动时确定,想自动扩缩容的工作负载请用soft。- 默认安装下,一张 GPU 同一时间只服务一种模式。在同一个池里随意混用
soft和hard,会让显卡用不满。尽量一个池统一用一种模式。
8. 不要手工设置 sidecar-worker
本地模式下的 hard 隔离会自动加上 worker sidecar,不需要这个注解。它还会强制使用本地模式,如果你本来想让工作负载跑在远程模式,结果会出乎意料。
优先级
9. 显式写出 QoS,critical 要少用
不写 qos 时,request 等于 limit 的 Pod 会成为 high,其他 Pod 取池的默认值或 medium。这种隐含规则很容易被忘记,所以请把等级写出来。high 和 critical 的 Pod 可以抢占低等级的 Pod;如果所有工作负载都是 critical,就等于没有优先级。
怎么选等级见创建 AI 应用。
调度位置
10. 位置约束够用就好
每多一个约束,调度器可选的显卡就少一些,Pod 也更容易 Pending。
- 工作负载确实依赖某个型号时才用
gpu-model。值从GPU资源的status.gpuModel复制,必须完全一致。 - 池里有多个加速卡厂商时使用
vendor。 gpu-indices留给调试和基准测试。它按卡号做硬性过滤,会让装箱失效。- 可用区或节点层面的约束,用常规的
nodeSelector和亲和性字段。
11. 多容器 Pod 一定要写明 GPU 容器
多容器 Pod 没有 inject-container 会被拒绝。即使有时能自动推断,也请自己列出容器名,这样以后加 sidecar 不会改变哪些容器能看到 GPU。多个容器需要各用各的卡时,再加上 container-gpu-count。
运维
12. 公共配置放进 WorkloadProfile
把团队通用的资源、QoS 和自动扩缩容配置放进 WorkloadProfile,个别值用注解覆盖。要记住:GPU 池、本地或远程模式、隔离模式不会从 profile 读取,这几项要写成注解。
13. 分阶段上线,验证 GPU 而不是 Pod 状态
用 tensor-fusion.ai/enabled-replicas 先迁几个副本。每个阶段都在已迁移的 Pod 里实际调用一次 CUDA;Pod 处于 Running 并不能说明 GPU 链路是通的。操作步骤见迁移现有应用。
14. 从 Pod 上读取实际生效的配置
webhook 会把解析后的取值写回 Pod,调度器还会加上分配到的 GPU。行为不符合预期时,先看这里:
kubectl describe pod <pod-name> | grep tensor-fusion.aiGPU 算力参考
把利用率换算成 TFLOPS,需要知道整卡的算力。对你的集群来说,最准确的数字是 TensorFusion 上报的容量:
kubectl get gpu -o custom-columns='NAME:.metadata.name,MODEL:.status.gpuModel,CAPACITY:.status.capacity'硬件还没到位、需要提前规划时,可以参考 TensorFusion 内置的常见 NVIDIA 显卡 FP16 TFLOPS:
| GPU | FP16 TFLOPS |
|---|---|
| T4 | 65 |
| L4 | 121 |
| A10、A10G | 125 |
| RTX 4090 | 165.16 |
| A100(40 GB 和 80 GB) | 312 |
| L40S | 365 |
| H100 PCIe | 835 |
| H100 SXM、H200 | 989 |
显存直接从设备读取,不在这张表里。
TensorFusion 文档