学院网站建设工作会议,wordpress处理大数据,织梦网站需要付费吗,网站开发报价合同原理GPU 既可以做物理分块#xff0c;也可以做虚拟分块。如果为了高效情况下,网卡也可以切分#xff08;VF#xff09;这两种方式在实现原理、隔离性、性能损耗和适用硬件上有本质区别。选择哪种方案取决于你的显卡型号#xff08;是否支持 MIG#xff09;以及业务对稳定性…原理GPU既可以做物理分块也可以做虚拟分块。如果为了高效情况下,网卡也可以切分VF这两种方式在实现原理、隔离性、性能损耗和适用硬件上有本质区别。选择哪种方案取决于你的显卡型号是否支持 MIG以及业务对稳定性的要求。1. 物理分块 (Physical Partitioning)代表技术NVIDIA MIG (Multi-Instance GPU)这是真正的“硬切”。显卡内部的计算单元、显存、缓存被硬件电路物理隔离成多个独立的实例。原理GPU 内部有专门的硬件逻辑如 A100 的 7 个切片每个切片拥有独立的 SM流多处理器、显存控制器和显存空间。操作系统和驱动看到的是多张独立的物理卡而不是“一张卡的一部分”。特点强隔离实例 A 崩溃、死机、显存溢出完全不会影响实例 B。就像两台不同的服务器。零干扰没有“邻居噪声”问题性能可预测。显存固定每个切片的显存大小是固定的例如 A100 40G 可以切成 7 个 5GB 的实例不能动态调整。重启需求开启或关闭 MIG 模式通常需要重启节点因为要重置 GPU 状态。硬件要求必须是支持 MIG 的高端卡A100, H100, H200, L40S, A30, A16等。RTX 3090/4090 或 T4/V100不支持此功能。K8s 表现Device Plugin 会上报多种资源类型例如nvidia.com/mig-1g.5gb,nvidia.com/mig-2g.10gb。Pod 请求的是具体的切片规格。适用场景多租户云环境、对稳定性要求极高的生产数据库/AI 服务、需要严格 SLA 保障的场景。2. 虚拟分块 (Virtual Partitioning / Time-Slicing)代表技术NVIDIA Time-Slicing (时间片轮转)这是“软切”。物理上显卡还是一整块通过驱动程序和调度器让多个进程轮流使用 GPU。原理所有 Pod 共享同一套物理计算单元和显存。NVIDIA 驱动在极短的时间窗口内微秒级快速切换上下文让多个进程觉得自己独占了 GPU。显存是共享池谁申请谁用直到爆满。特点弱隔离如果实例 A 跑满算力实例 B 会变慢如果实例 A 显存泄漏OOM可能导致整个节点上的其他 Pod 也被杀掉因为显存是共享的。性能损耗存在上下文切换开销且并发高时延迟增加。配置灵活可以通过 ConfigMap 随意设置“虚拟倍数”例如把 1 张卡虚拟成 2 张、4 张甚至 10 张。无需重启修改配置重启 Device Plugin 即可生效不需要重启服务器。硬件要求几乎所有支持 CUDA 的 NVIDIA 显卡都支持包括消费级的 RTX 3090/4090数据中心的 T4, V100, A10 等。K8s 表现Device Plugin 上报的资源数量变多了。原本nvidia.com/gpu: 1变成nvidia.com/gpu: 4。Pod 依然请求nvidia.com/gpu: 1但底层其实是共享的。适用场景开发测试环境、推理服务负载不饱和、成本敏感型业务、使用不支持 MIG 的旧款/消费级显卡。3. 核心对比表表格特性物理分块 (MIG)虚拟分块 (Time-Slicing)隔离级别硬件级(进程崩溃互不影响)进程级(显存/CPU 争抢可能互相影响)显存管理固定分配严格限制共享池容易 OOM (需应用层控制)性能确定性高 (像独占一样稳)中/低 (受邻居负载影响大)支持的显卡仅限高端(A100/H100/L40S等)全部(T4/V100/RTX系列等)配置复杂度高 (需规划切片大小常需重启节点)低 (改个 ConfigMap 数字即可)超卖风险低 (物理隔离保证安全)高 (容易因显存溢出导致集体崩溃)K8s 资源名动态变化 (如mig-1g.5gb)保持不变 (nvidia.com/gpu)4. 还有一种“中间态”vGPU (虚拟化显卡)除了上述两种原生方案还有基于NVIDIA vGPU Software(需购买 License) 的方案。原理在宿主机上运行一个 Hypervisor 层将 GPU 虚拟化成标准的 vGPU 透传给 VM 或容器。特点支持更细粒度的显存切分不像 MIG 那样固定几种规格支持更多老款专业卡如 Tesla P/T 系列的部分型号。缺点贵需要按年付费买 License架构复杂通常需要配合 Citrix 或 VMware 等虚拟化平台虽然现在也支持 K8s Direct 模式但依然复杂。5. 决策建议我该选哪个情况 A你用的是 A100 / H100 / L40S首选物理分块 (MIG)。既然买了这么贵的卡就要利用其硬件隔离特性确保多租户安全。除非你的业务非常特殊需要非标准显存大小否则不要浪费 MIG 的优势去用时间片。情况 B你用的是 T4 / V100 / RTX 3090 / 4090只能选虚拟分块 (Time-Slicing)。这些卡不支持物理切分。注意在使用 Time-Slicing 时务必在应用代码中限制显存使用量例如 PyTorch 中设置max_memory防止一个 Pod 吃光显存导致其他 Pod 崩溃。情况 C混合部署你可以在同一个集群中同时开启两种模式如果硬件允许。节点组 A (A100)开启 MIG跑核心生产任务。节点组 B (T4/RTX)开启 Time-Slicing (replicas4)跑开发测试或低成本推理任务。总结物理分块真分割安全、稳定、贵、挑硬件。虚拟分块假分割灵活、便宜、有风险、通用性强。对于大多数初创公司或使用消费级显卡搭建的集群虚拟分块 (Time-Slicing)是最具性价比的超卖方案而对于大型云厂商或关键业务物理分块 (MIG)是必选项。那切分是需要调用显卡的apiQwen3.5-Plus10:51:39不需要你的业务代码调用任何特殊的 API。这是一个非常关键的误区澄清切分无论是物理 MIG 还是虚拟 Time-Slicing对上层应用是“透明”的。1. 核心原理谁在干活你的代码 (PyTorch/TensorFlow/CUDA C)完全无感知。你写的代码依然是标准的torch.cuda.is_available(),model.to(cuda),tensor.cuda()。你的代码以为它独占了一整张显卡。NVIDIA 驱动 Device Plugin真正干活的层。它们在操作系统内核层和容器运行时层拦截了资源请求。当你申请nvidia.com/gpu: 1时K8s 调度器把你调度到节点上然后 Kubernetes 的Device Plugin会告诉 Docker/Containerd“把这个容器的环境变量NVIDIA_VISIBLE_DEVICES设置为MIG-xxx(物理) 或者0(虚拟共享)”。NVIDIA 驱动接收到这个信号后会在底层限制该进程只能访问被切分出来的那部分资源。2. 具体场景解析场景 A物理切分 (MIG)操作者集群管理员在节点初始化时。动作管理员使用nvidia-smi命令或重启节点时配置将物理卡切成mig-1g.5gb,mig-2g.10gb等逻辑卡。结果操作系统里出现了多张新的“伪”物理卡。原本GPU 0(A100 40G)切分后GPU 0(MIG 5G),GPU 1(MIG 5G)...GPU 6(MIG 5G)。你的代码python# 你的代码完全不用改 import torch print(torch.cuda.device_count()) # 如果调度器分给你一个 MIG 切片这里显示 1。 # 你的代码看到的就是一张 5GB 显存的“普通显卡”。结论不需要调 API因为对 OS 来说它真的就是几张独立的小卡。场景 B虚拟切分 (Time-Slicing)操作者集群管理员修改 K8s ConfigMap。动作管理员在nvidia-device-plugin-config中设置replicas: 4。结果K8s 认为节点有 4 个 GPU 资源。当 4 个 Pod 同时启动时NVIDIA 驱动会让这 4 个进程轮流使用同一块物理 GPU 的计算单元。这种“轮流”是由驱动程序的时间片调度器在内核态完成的类似于 CPU 的时间片轮转。你的代码python# 你的代码依然完全不用改 # 你以为你独占了 GPU实际上驱动在微秒级切换上下文。 model.to(cuda)结论不需要调 API这是驱动层的“黑魔法”。3. 什么时候才需要调用 API只有在极少数高级优化场景下你的代码才需要感知切分显存精细管理 (防止 OOM)在虚拟切分模式下因为显存是共享的如果你的代码不限制显存使用可能会瞬间吃光所有显存导致同节点的其他 Pod 崩溃。做法虽然不是切分 API但你需要在代码里限制显存增长。PyTorch 示例pythonimport torch # 限制 PyTorch 只使用 2GB 显存防止撑爆共享池 torch.cuda.set_per_process_memory_fraction(0.5, 0)指定特定的 MIG 切片 (极少见)通常 K8s 会自动把正确的切片 ID 注入到容器环境变量NVIDIA_VISIBLE_DEVICES中。除非你在一个容器内想手动切换访问不同的 MIG 切片例如做测试否则不需要手动指定。监控与遥测如果你想在自己的程序里知道“我现在是在一个 MIG 切片上运行还是在全卡上运行”可以调用pynvml库查询设备属性。但这只是为了看不是为了用。K8S使用在 Kubernetes (K8s) 中“动态管理”的核心在于你不需要在 Pod YAML 里写“我要切分”而是通过请求特定的“资源名称”来让 K8s 自动调度到对应的分片上。K8s 的调度器Scheduler只认资源名称Resource Name和数量。底层的物理切分硬或虚拟切分软是由Node节点和Device Plugin暴露给 K8s 的。以下是针对硬切 (MIG)和软切 (Time-Slicing)的具体动态管理流程一、硬切 (MIG) 的动态管理核心逻辑MIG 将一张物理卡变成了多张不同规格的逻辑卡。K8s 会把它们视为完全不同的资源类型。1. 准备阶段 (管理员操作)首先必须在节点上启用 MIG 模式并创建实例。这通常是一次性的或通过 Node Feature Discovery 自动完成。动作使用nvidia-smi mig -cgi命令将 GPU 0 切分为 3 个1g.5gb和 2 个2g.10gb。结果NVIDIA Device Plugin 启动后会向 K8s API Server 注册新的资源类型nvidia.com/mig-1g.5gb(数量: 3)nvidia.com/mig-2g.10gb(数量: 2)注意原本的nvidia.com/gpu可能不再可用或数量为 0。2. 调度阶段 (Pod YAML)当你想要 Pod 走其中一个分片时你只需要在resources.limits中请求对应的资源名称。apiVersion: v1 kind: Pod metadata: name: mig-small-job spec: containers: - name: cuda-container image: nvidia/cuda:12.0-base resources: limits: # 【关键】这里写的资源名必须与节点上报的完全一致 nvidia.com/mig-1g.5gb: 1 # 如果你想用大一点的分片就改成 nvidia.com/mig-2g.10gb: 1 command: [nvidia-smi] args: [-L]3. K8s 的动态行为调度K8s 调度器看到你的 Pod 需要nvidia.com/mig-1g.5gb: 1。它会遍历所有节点找到拥有该剩余资源的节点例如 Node-A 还有 1 个空闲。绑定调度器将 Pod 绑定到 Node-A。注入kubelet 调用 Device PluginDevice Plugin 告诉容器运行时“把这个 Pod 的NVIDIA_VISIBLE_DEVICES环境变量设置为MIG-uuid-of-that-slice”。结果Pod 启动后里面看到的就是一张独立的 5GB 显存显卡。动态扩缩容如果你删除了 Pod资源释放K8s 计数加 1下一个请求该资源的 Pod 可以立刻调度上去。完全自动化。二、软切 (Time-Slicing) 的动态管理核心逻辑软切不改变资源名称只是增加了可用数量。所有 Pod 都请求标准的nvidia.com/gpu但底层驱动让它们共享。1. 准备阶段 (管理员操作)管理员修改nvidia-device-plugin的 ConfigMap设置replicas。配置设置nvidia.com/gpu的replicas: 4。结果假设节点有 1 张物理 T4 卡。Device Plugin 会向 K8s 上报nvidia.com/gpu: 4 (原本是 1)注意资源名称没变还是nvidia.com/gpu只是容量变大了。2. 调度阶段 (Pod YAML)Pod 的写法完全不需要改变和独占显卡一样。apiVersion: v1 kind: Pod metadata: name: time-slice-job-1 spec: containers: - name: cuda-container image: nvidia/cuda:12.0-base resources: limits: # 【关键】依然请求标准资源K8s 会认为还有 4 个名额 nvidia.com/gpu: 13. K8s 的动态行为调度Pod 1 来了 - 占用 1 个配额 (剩余 3)。Pod 2 来了 - 占用 1 个配额 (剩余 2)。...Pod 4 来了 - 占用 1 个配额 (剩余 0)。Pod 5 来了 -Pending(因为配额没了即使物理卡还在逻辑上已满)。共享执行这 4 个 Pod 会被调度到同一张物理卡上。NVIDIA 驱动在底层通过时间片轮转让它们并发运行。注入所有 4 个 Pod 的NVIDIA_VISIBLE_DEVICES都被设置为0(即那张物理卡的 ID)但驱动内部做了上下文隔离。动态风险K8s 只管“数量”不管“显存容量”。如果 4 个 Pod 每个都想用 10GB 显存总共 40GB而物理卡只有 16GBPod 会启动但在运行时会因为 OOM (Out Of Memory) 崩溃。这需要应用层自己控制显存使用量。三、总结对比如何“指定”分片表格特性硬切 (MIG)软切 (Time-Slicing)如何指定分片修改 YAML 中的资源名称。例如nvidia.com/mig-1g.5gbvsnvidia.com/mig-2g.10gb。无法在 YAML 中指定具体分片。所有 Pod 都写nvidia.com/gpu: 1由调度器按顺序分配“坑位”。K8s 视角看到了多种不同的资源类型。只看到一种资源类型但数量变多了。隔离性强。Pod A 只能访问它被分配的那个切片 UUID。弱。所有 Pod 都能看到整张卡靠驱动强制排队。适用场景需要明确区分“小任务”和“大任务”。例小任务申请mig-1g大任务申请mig-3g。任务同质化且负载不高。例大家都跑小模型推理谁先来谁先用。动态调整难度难。如果要改变分片大小如从 1g 改成 2g通常需要重启节点重新划分 MIG。易。修改 ConfigMap 中的replicas数字重启 Device Plugin 即可动态生效无需重启节点。四、实战如何动态切换场景 1我想让某个重要 Pod 独占一个大分片 (MIG)确保节点已配置好 MIG 实例例如存在mig-3g.20gb。修改 Pod YAMLyamlresources: limits: nvidia.com/mig-3g.20gb: 1kubectl apply。K8s 会自动寻找有该资源的节点并调度。场景 2我想临时增加共享人数 (Time-Slicing)编辑 ConfigMapbashkubectl edit configmap nvidia-device-plugin-config -n kube-system将replicas: 2改为replicas: 8。重启 Device Pluginbashkubectl rollout restart daemonset nvidia-device-plugin -n kube-system瞬间生效现在该节点可以容纳 8 个请求nvidia.com/gpu: 1的 Pod 了。现有的 Pod 不受影响新的 Pod 可以进来共享。核心结论硬切 (MIG)靠资源名称区分。你在 YAML 里写什么名字K8s 就给你调度哪种规格的物理切片。软切 (Time-Slicing)靠资源数量堆叠。你在 YAML 里写的都一样K8s 只是允许更多的 Pod 进入同一个节点“挤一挤”。你不需要调用任何 API 去“连接”分片只要 YAML 里的resources.limits写对了K8s 和 Device Plugin 会自动帮你把 Pod“塞”进正确的分片里。查询算力和显存方法一节点级查看最快适合排查宿主机问题直接在运行 Pod 的物理节点上执行命令。这是最准确、延迟最低的方式。1. 实时查看nvidia-smi# 每 1 秒刷新一次 watch -n 1 nvidia-smi关键字段解读2. 查看历史/详细统计nvidia-smi dmon如果需要记录数据或看更细粒度的指标# 每秒采样一次输出到终端 nvidia-smi dmon -s uvmectp -c 1方法二容器/Pod 级查看最常用适合排查具体业务在 K8s 中一个节点可能跑着多个 Pod。你想知道特定 Pod占用了多少资源而不是整张卡。方案 A使用kubectl top(需安装 Metrics Server NVIDIA Device Plugin 支持)较新的 NVIDIA Device Plugin 版本支持将 GPU 指标暴露给 K8s Metrics API。# 查看指定 Pod 的 GPU 使用情况 kubectl top pod pod-name -n namespace方案 B进入容器内部查询 (通用性最强)如果kubectl top没数据可以直接 exec 进容器查前提是容器内有nvidia-smi或/proc权限。方案 C使用dcgm-exporter(推荐生产环境)NVIDIA 官方推出的DCGM (Data Center GPU Manager)是监控神器。方法三集群级可视化 (Grafana)如果你需要长期观察或给老板看报表必须搭建Prometheus Grafana。四、指标解读与优化建议拿到数据后如何判断是否正常表格场景算力 (Util)显存 (Mem)诊断与建议训练饱和90% - 100%高 (接近 Limit)完美状态。显卡在全力工作。IO 瓶颈低 (30%)波动或稳定数据加载太慢。CPU 预处理或磁盘读取跟不上 GPU 计算速度。优化增加 DataLoader workers, 使用 SSD, 预取数据。算子瓶颈中 (40-60%)稳定代码效率低。可能存在大量的 CPU-GPU 数据拷贝或使用了非融合算子。优化检查 PyTorch Profiler, 启用 AMP 混合精度。显存泄漏任意持续上升直到 OOM代码 Bug。Tensor 没有释放或被意外引用。优化检查.item(),.detach(), 全局列表累积。碎片化低高 (但模型很小)显存碎片。频繁分配释放不同大小的显存导致无法分配连续大块。优化设置PYTORCH_CUDA_ALLOC_CONFmax_split_size_mb:512。超卖冲突忽高忽低频繁触顶邻居干扰(Time-Slicing 模式)。同一卡上的其他 Pod 在抢资源。优化迁移到独占节点或开启 MIG。五、快速检查脚本 (Copy-Paste)如果你想在 K8s 里快速写个脚本监控某个 Pod#!/bin/bash POD_NAME$1 NAMESPACE${2:-default} echo Monitoring GPU for pod: $POD_NAME in namespace: $NAMESPACE echo ---------------------------------------- while true; do # 尝试在容器内执行 nvidia-smi OUTPUT$(kubectl exec $POD_NAME -n $NAMESPACE -- nvidia-smi --query-gpuindex,utilization.gpu,memory.used,memory.total --formatcsv,noheader,nounits 2/dev/null) if [ $? -eq 0 ]; then clear echo Time: $(date) echo GPU-ID | Util(%) | Mem-Used(MiB) | Mem-Total(MiB) echo $OUTPUT | sed s/,/ | /g else echo Error: Cannot exec nvidia-smi in container. Maybe image lacks tools or permissions. # 降级方案看 K8s metrics (如果可用) kubectl top pod $POD_NAME -n $NAMESPACE --containers 2/dev/null || echo Metrics server not available. fi sleep 2 done使用方法./check_gpu.sh my-training-pod default总结查看 GPU 的算力利用率GPU Utilization和显存利用率Memory Utilization是监控和优化 AI 任务的关键。在 Kubernetes 环境中通常有三种层级的查看方式节点级物理机视角看整张卡的总负载。容器/Pod 级业务视角看具体某个任务的负载最常用。集群级大盘视角通过 Prometheus Grafana 看整体趋势。Volatile GPU-Util算力利用率。表示 GPU 计算单元在过去一秒内处于忙碌状态的时间百分比。注意如果是显存带宽密集型任务如大模型推理的 Prefill 阶段算力可能不高但速度依然很慢。Memory-Usage显存利用率。格式为已用 / 总量(例如10240MiB / 40960MiB)。Processes底部列表显示当前占用 GPU 的进程 PID 和显存占用。-s uvmectp: 监控 util (算力), mem (显存), ecc (错误), temp (温度), power (功耗)。输出示例textNAME CPU(cores) MEMORY(bytes) GPU(cores) GPU Memory(bytes) my-ai-pod 200m 512Mi 85% 10240Mi前提集群必须部署了支持指标上报的nvidia-device-plugin(通常需开启--metrics-listen-address) 并配置了metrics-server。进入容器bashkubectl exec -it pod-name -n namespace -- bash在容器内运行bashnvidia-smi原理K8s 通过NVIDIA_VISIBLE_DEVICES环境变量限制了容器只能看到分配给它的 GPU 切片。因此容器内运行的nvidia-smi只会显示该 Pod 独占的那部分资源无论是 MIG 切片还是 Time-Slicing 的逻辑视图。判断如果容器内看到GPU-Util: 99%说明你的代码把分到的算力跑满了。如果容器内看到Memory-Usage: 15GB / 20GB说明你的模型加载占了 15G。部署dcgm-exporterDaemonSet。它会采集每个容器通过 cgroup 隔离的 GPU 指标。你可以直接查询 Prometheus 获取特定 Pod 的指标promql# 查询特定 Pod 的 GPU 利用率 DCGM_FI_DEV_GPU_UTIL{containerpod-name} # 查询特定 Pod 的显存使用量 (字节) DCGM_FI_DEV_MEM_COPY_UTIL{containerpod-name} # 注意显存通常看 used memory 指标 DCGM_FI_DEV_FB_USED{containerpod-name}架构Node Exporter (采集 CPU/内存)DCGM Exporter(采集 GPU 核心指标必装)Prometheus (存储数据)Grafana (展示图表)推荐 DashboardNVIDIA 官方提供了现成的 Grafana JSON 模板ID:12239或15456。导入后你可以直接看到每张卡的算力热力图。每个 Namespace 的显存总消耗。特定 Pod 的历史利用率曲线。临时排查kubectl exec进去跑nvidia-smi。日常运维部署dcgm-exporterGrafana。核心指标关注GPU-Util(是否吃饱) 和FB Memory Usage(是否撑爆)。