工作负载配置
工作负载申请和配置 vGPU 资源所用的标签、Pod 注解和 WorkloadProfile 字段参考。
工作负载通过 Pod 模板上的一个标签和一组注解申请 vGPU 资源。本页列出 TensorFusion webhook 读取的全部注解,以及它们的类型、默认值和取值范围。
取值规则
所有键都以 tensor-fusion.ai/ 为前缀。注解的值是字符串,数字和布尔值要加引号:"2"、"true"。
同一项配置按下面的顺序取第一个有值的来源:
- Pod 注解。
tensor-fusion.ai/workload-profile指向的WorkloadProfile。- 对资源的 request 和 limit:namespace 下
GPUResourceQuota的spec.single.defaultRequests和spec.single.defaultLimits。 - 本页列出的默认值。
不合法的 Pod 会在创建时被 webhook 拒绝。对 Deployment 来说,报错出现在 ReplicaSet 的事件里。
标签
| 标签 | 取值 | 含义 |
|---|---|---|
tensor-fusion.ai/enabled | "true"、"false" | "true" 表示把 Pod 交给 TensorFusion。没有这个标签时 webhook 不处理该 Pod,除非开启了自动迁移。"false" 表示不参与自动迁移。 |
tensor-fusion.ai/host-port | auto | 让 TensorFusion 给 TensorFusion Pod 的某个容器端口分配一个 host port。需要同时设置 tensor-fusion.ai/port-name。 |
tensor-fusion.ai/port-name | 容器端口名 | 接收 host port 的端口名。分配到的端口号写在注解 tensor-fusion.ai/port-number 里。 |
资源注解
| 注解 | 类型 | 默认值 | 含义 |
|---|---|---|---|
tensor-fusion.ai/tflops-request | Quantity,例如 "10" | tflops-limit 的值 | 在每张 GPU 上为工作负载预留的算力,单位 TFLOPS(FP16)。 |
tensor-fusion.ai/tflops-limit | Quantity | 无 | 工作负载在每张 GPU 上最多可用的算力,单位 TFLOPS。 |
tensor-fusion.ai/vram-request | Quantity,例如 4Gi | vram-limit 的值 | 在每张 GPU 上为工作负载预留的显存。 |
tensor-fusion.ai/vram-limit | Quantity | 无 | 工作负载在每张 GPU 上最多可用的显存。 |
tensor-fusion.ai/compute-percent-request | 数字,例如 "30" | compute-percent-limit 的值 | 预留的算力,按单卡百分比表示。可替代 tflops-request。 |
tensor-fusion.ai/compute-percent-limit | 数字 | 无 | 最多可用的算力,按单卡百分比表示。可替代 tflops-limit。 |
规则:
tflops-request、compute-percent-request、vram-request中至少有一个最终不为 0。例外:isolation: shared,以及带partition-id的isolation: partitioned。- TFLOPS 和百分比二选一。同一个 Pod 上两类注解都写了时,以 TFLOPS 为准,百分比被忽略。如果 TFLOPS 和百分比分别来自不同来源,Pod 会被拒绝。
- 同一个百分比在不同型号的 GPU 上代表不同的算力,而且不计入 namespace 的 GPU 配额。优先使用 TFLOPS;只有池里只有一种 GPU 型号、又不需要租户配额时才用百分比。
- 不是合法 Kubernetes Quantity 的值视为未设置。
gpu-count大于 1 时,这些值对每张 GPU 分别生效。
调度位置注解
| 注解 | 类型 | 默认值 | 含义 |
|---|---|---|---|
tensor-fusion.ai/gpupool | GPUPool 名称 | 默认池 | 从哪个池分配。池不存在,或者没写注解而集群又没有默认池时,Pod 被拒绝并报 gpu pool not found。 |
tensor-fusion.ai/gpu-count | 整数,1 到 128 | 1 | 每个 Pod 使用的 GPU 数量。 |
tensor-fusion.ai/gpu-model | 字符串 | 不限型号 | 只使用这个型号的 GPU。必须与 GPU 资源的 status.gpuModel 完全一致。 |
tensor-fusion.ai/vendor | 字符串 | 不限厂商 | 只使用这个厂商的 GPU。必须与 GPU 资源的 status.vendor 完全一致,例如 NVIDIA、AMD、Ascend、MooreThreads、PPU。使用非 NVIDIA 的加速卡时要写明。 |
tensor-fusion.ai/gpu-indices | 逗号分隔的整数,例如 "0,1" | 无 | 只使用节点上这些设备序号的 GPU。这是硬性过滤条件。设置后,GPU 数量等于序号的个数。 |
tensor-fusion.ai/dedicated-gpu | "true" | 未设置 | 申请每张 GPU 的全部 TFLOPS 和显存。必须同时设置 gpu-model,并且集群里已经发现了至少一张该型号的 GPU。它只补全 request 和 limit,不改变隔离模式。 |
查看池里有哪些型号和厂商:
kubectl get gpu -o custom-columns='NAME:.metadata.name,VENDOR:.status.vendor,MODEL:.status.gpuModel,CAPACITY:.status.capacity'模式注解
| 注解 | 类型 | 默认值 | 含义 |
|---|---|---|---|
tensor-fusion.ai/is-local-gpu | "true"、"false" | 池的 defaultUsingLocalGPU,未设置时为 true | "true":本地 GPU 模式。Pod 由 TensorFusion 调度器调度到 GPU 节点,直接使用显卡。"false":远程 vGPU 模式。Pod 可以运行在任意节点,通过网络访问 GPU 节点上独立的 worker Pod。 |
tensor-fusion.ai/isolation | shared、soft、hard、partitioned | soft | 工作负载与同一张 GPU 上其他工作负载的隔离方式,见下表。 |
tensor-fusion.ai/sidecar-worker | "true" | 未设置 | 把 vGPU worker 作为 sidecar 容器放进 Pod,并强制使用本地 GPU 模式。本地模式下的 hard 隔离不管是否设置它,都会使用 sidecar worker。 |
tensor-fusion.ai/partition-id | 分区模板 ID | 无 | isolation: partitioned 时使用的分区模板。不写时,选择能满足资源请求的最小模板。 |
tensor-fusion.ai/qos | low、medium、high、critical | 见下文 | 服务质量等级。 |
tensor-fusion.ai/worker-pod-template | PodTemplateSpec 的 YAML | 无 | worker Pod 的附加 Pod 模板。只用于远程 vGPU 模式,本地模式下会被拒绝。 |
隔离模式:
| 模式 | 行为 | 约束 |
|---|---|---|
shared | 申请的每张 GPU 都整卡分配。不注入任何组件,也不做任何限制。 | 不需要 TFLOPS 或显存注解。 |
soft | 在容器里预加载限流库,由它执行 TFLOPS 和显存 limit。多个 Pod 共用一张卡。 | 支持 NVIDIA、Ascend、MooreThreads、PPU。AMD、Hygon、MetaX 会被拒绝。 |
hard | 由 vGPU worker 持有 GPU 并执行限额,限额在 worker 启动时确定。 | 本地模式下会给 Pod 加一个 tensorfusion-worker sidecar 容器。 |
partitioned | 由驱动或硬件切分 GPU,例如 NVIDIA MIG。 | 需要硬件支持。controller 使用 isolationModePolicy: dynamic(Helm 默认值)时不可用。 |
在默认的 dynamic 隔离策略下,一张 GPU 同一时间只服务一种隔离模式。正在运行 soft 工作负载的卡,要等清空之后才能接收 hard 工作负载,反过来也一样。
QoS 的默认值:TFLOPS 和显存的 request 都等于各自的 limit 且不为 0 时为 high;否则取池的 qosConfig.defaultQoS;池也没配时为 medium。high 和 critical 的 Pod 如果没有 priorityClassName,会被设为 tensor-fusion-high 或 tensor-fusion-critical。
容器注解
| 注解 | 类型 | 默认值 | 含义 |
|---|---|---|---|
tensor-fusion.ai/inject-container | 逗号分隔的容器名 | Pod 里唯一的容器 | 使用 GPU 的容器。Pod 有多个容器时必须设置。找不到对应容器的名字会被忽略;一个都匹配不上时,Pod 原样放行。 |
tensor-fusion.ai/container-gpu-count | JSON 对象,例如 '{"trainer":2,"eval":1}' | 所有被注入的容器都能看到全部 GPU | 每个容器使用的 GPU 数量。按容器名的字母顺序从 Pod 的 GPU 里依次分配,所以各容器数量之和不能超过 gpu-count。 |
灰度与 Profile 注解
| 注解 | 类型 | 默认值 | 含义 |
|---|---|---|---|
tensor-fusion.ai/workload-profile | WorkloadProfile 名称 | 无 | Pod 所在 namespace 里提供默认配置的 profile。profile 不存在时 Pod 被拒绝。 |
tensor-fusion.ai/enabled-replicas | 整数 | 全部副本 | TensorFusion 最多接管这个工作负载的多少个 Pod,其余 Pod 原样放行。用于灰度上线,只对有控制器的 Pod 生效。 |
自动扩缩容注解
| 注解 | 类型 | 默认值 | 含义 |
|---|---|---|---|
tensor-fusion.ai/autoscale | "true" | 未设置 | 按历史用量调整 request 和 limit。 |
tensor-fusion.ai/autoscale-target | compute、vram、all | all | 调整哪种资源。只有 autoscale 为 "true" 时才读取。 |
详见配置自动扩缩容。
Gang 调度注解
Gang 调度让一组 Pod 只有在足够多的成员能同时放下时才一起启动。
| 注解 | 类型 | 默认值 | 含义 |
|---|---|---|---|
tensor-fusion.ai/gang-enabled | "true" | 未设置 | 开启 Gang 调度。工作负载至少要有 2 个副本。 |
tensor-fusion.ai/gang-min-members | 整数,0 或不小于 2 | 0 | 必须能同时调度的 Pod 数量。0 表示全部副本。不能大于副本数。 |
tensor-fusion.ai/gang-timeout | 时长,例如 5m | 一直等待 | 等待成员凑齐的最长时间。0 或 0s 同样表示一直等待。 |
副本数依次从 enabled-replicas、profile 的 replicas、所属控制器的 spec.replicas、spec.parallelism、spec.completions 读取。
调试注解
| 注解 | 类型 | 含义 |
|---|---|---|
tensor-fusion.ai/disable-features | 逗号分隔,可选 gpu-limiter、gpu-opt、mem-manager、start-worker | 排障时关闭 vGPU client 和 worker 的内置功能。start-worker 让 worker 容器空转,方便手动启动 worker。只在注入了 vGPU client 库或 worker 的情况下生效,即远程 vGPU 模式和本地 sidecar worker。本地的 soft、shared、partitioned 模式下不起作用。不要在生产环境使用。 |
原生 GPU 资源
启用了 TensorFusion 的 Pod,如果容器的 resources.limits 里还有 nvidia.com/gpu 这类 device plugin 资源,并且 gpu-count 注解和 profile 都没有指定 GPU 数量,webhook 会从它推导出请求:
- GPU 数量等于所有容器 limit 之和。
compute-percent-limit设为100,除非isolation为shared或设置了tflops-*注解。- 厂商、
inject-container、container-gpu-count根据带有该 limit 的容器自动填写。 - 被注入的容器上,原生资源会被去掉。
详见迁移现有应用。
由 TensorFusion 写入
下面这些键由 TensorFusion 写在 Pod 上,排障时可以查看,不要自己设置。
| 键 | 类别 | 含义 |
|---|---|---|
tensor-fusion.ai/gpu-ids | 注解 | 调度器分配的 GPU 名称。远程模式下写在 worker Pod 上。 |
tensor-fusion.ai/container-gpus | 注解 | 每个容器分到的 GPU,设置了 container-gpu-count 时写入。 |
tensor-fusion.ai/effective-hard-sm-percent | 注解 | hard 隔离的工作负载由 tflops-limit 换算出的算力百分比。 |
tensor-fusion.ai/partition-uuids | 注解 | 为 partitioned 工作负载创建的分区实例。 |
tensor-fusion.ai/selected-workload | 注解 | 远程模式的 Pod 所连接的 TensorFusionWorkload 名称。 |
tensor-fusion.ai/port-number | 注解 | 通过 host-port 标签分配到的 host port。 |
tensor-fusion.ai/gang-desired-members、gang-required-members、gang-group-key | 注解 | 解析出的 Gang 规模和分组。 |
tensor-fusion.ai/workload | 标签 | 所属 TensorFusionWorkload 的名称,写在持有 GPU 的 Pod 上。 |
tensor-fusion.ai/gpupool | 标签 | Pod 被分配到的池。 |
tensor-fusion.ai/component | 标签 | 持有 GPU 的 Pod 为 worker,远程模式的业务 Pod 为 client。 |
webhook 还会把解析后的取值写回 Pod 的注解,所以 kubectl get pod -o yaml 能看到实际生效的 request、limit、QoS、池、GPU 数量、隔离模式和运行模式。
WorkloadProfile
WorkloadProfile 包含与注解相同的配置项,另外还有一些没有注解形式的字段,例如自动扩缩容的详细配置(autoScalingConfig)。Gang 调度也可以在这里用 gangScheduling 配置。它必须和 Pod 在同一个 namespace。
apiVersion: tensor-fusion.ai/v1
kind: WorkloadProfile
metadata:
name: example-profile
namespace: default
spec:
resources:
requests:
tflops: "5"
vram: 3Gi
limits:
tflops: "15"
vram: 3Gi
qos: medium
gpuCount: 1
vendor: NVIDIA
autoScalingConfig:
autoSetResources:
enable: true
targetResource: all在 Pod 上引用它:
metadata:
annotations:
tensor-fusion.ai/workload-profile: example-profilePod 准入时,profile 里有三个字段不会被读取:poolName、isLocalGPU、isolation。请用 gpupool、is-local-gpu、isolation 注解设置,或者使用池的默认值。gpuIndices 同样只从注解读取。
全部字段见 WorkloadProfile Schema。
完整示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: inference
spec:
replicas: 2
selector:
matchLabels:
app: inference
template:
metadata:
labels:
app: inference
tensor-fusion.ai/enabled: "true"
annotations:
tensor-fusion.ai/inject-container: "server"
tensor-fusion.ai/tflops-request: "10"
tensor-fusion.ai/tflops-limit: "20"
tensor-fusion.ai/vram-request: "4Gi"
tensor-fusion.ai/vram-limit: "4Gi"
tensor-fusion.ai/qos: "high"
tensor-fusion.ai/is-local-gpu: "true"
tensor-fusion.ai/isolation: "soft"
tensor-fusion.ai/gpu-count: "1"
spec:
containers:
- name: server
image: pytorch/pytorch:2.4.1-cuda12.1-cudnn9-runtime
command: ["sh", "-c", "sleep infinity"]
- name: log-shipper
image: busybox:1.36
command: ["sh", "-c", "sleep infinity"]
TensorFusion 文档