
1. 为什么海光 DCU 进 Kubernetes 是绕不开的一步先说一个我在实际交付中反复遇到的场景客户手里有一批海光 DCU 算力卡想在上面跑 DeepSeek 这类开源大模型同时还要接进公司已有的 Kubernetes 集群让算法团队像用 GPU 一样按需申请资源。听起来很常规但真做起来会发现海光 DCU 的接入和 NVIDIA GPU 那一套完全是两码事。nvidia.com/gpu 这种资源调度方式在海光平台上不可用因为 DCU 的驱动、运行时、设备插件都是独立的生态。如果只是把机器加进集群、装个驱动就完事Kubernetes 根本感知不到 DCU 的存在调度器不会把 Pod 调度到这些节点上。强行用 hostPath 把/dev/dri映射进容器虽然能跑但整颗卡被单个任务独占别的任务只能干等谈不上资源管理。CubeStudio 这类 AI 平台之所以在国产算力适配里有价值是因为它补齐了 Kubernetes 原生调度的短板设备插件、资源上报、共享调度、虚拟化切分、镜像封装这些能力都有了比较成熟的落地路径。这篇把我实际做过的接入方案、两种 vDCU 虚拟化方式的取舍、以及 DeepSeek 部署的完整链路都梳理一遍给正在做同样事情的人一个可以直接参考的样本。需要说明的是具体版本号和参数会随驱动、内核、Kubernetes 版本变化但整体架构和排查思路是通用的。2. 接入前必须搞清楚的几个底层事实2.1 DCU 与 GPU 在虚拟化路径上的本质差异海光 DCU 基于 ROCm 生态衍生而来硬件上采用 CDNA 架构类似的设计思路但在软件栈上做了大量国产化适配。这意味着很多 NVIDIA 生态里的成熟组件不能直接搬过来用最典型的就是 CUDA 的 MPSMulti-Process Service和 vGPU 方案在 DCU 上没有对应版本。整卡分配是最容易实现的路径把物理卡直接 passthrough 给 Pod性能损耗小但资源利用率低。共享是下一个层次让多个 Pod 共用一张物理卡靠的是 runtime 层面的时间片或者并发隔离。再往上就是 vDCU 虚拟化这是海光平台真正拉开差距的地方后面专门讲。这里想强调一个容易踩坑的点DCU 的驱动和 ROCm 运行时版本必须匹配。见过好几个人上来就装最新版 ROCm结果内核模块加载失败因为海光 DCU 的驱动是随厂商发布周期走的不能拿 AMD 的开源 ROCm 直接套。建议直接用官方仓库里的驱动先确认内核版本兼容性再动手装。2.2 K8s 设备接入的技术选型Device Plugin 与 CRD 扩展Kubernetes 原生支持通过 Device Plugin 框架接入外部设备资源这是最标准的路径。Device Plugin 负责向 kubelet 上报设备数量、健康状态并实现分配逻辑。但 Device Plugin 有一个限制它分配出去的资源无法感知 Pod 内部具体如何使用也没有办法在容器内做更细粒度的资源切分。要实现 vDCU 这种虚拟化资源需要配合 CRDCustom Resource Definition做更上层的调度控制。我当前推荐的选型是能力Device Plugin 方案CRD Device Plugin 方案整卡分配支持支持健康检查kubelet 定期调用扩展了细粒度状态共享切分依赖插件实现可配合虚拟化层做资源切分调度感知仅按数量调度支持更丰富的调度语义很明显生产级方案一定会走到 CRD Device Plugin 的组合路线上。CubeStudio 的适配方案也是这个思路只是它在 CRD 之上做了平台层的资源抽象用户层面不需要关心底层 CRD 的细节。3. CubeStudio 海光 DCU 适配的整体架构与核心模块3.1 架构分层的核心逻辑CubeStudio 接入海光 DCU 时整个链路从上到下大概是这个样子的用户通过平台界面提交任务声明需要的 DCU 资源类型、数量、虚拟化方式平台根据资源声明和集群状态通过 CRD 和调度器扩展完成 Pod 与 DCU 的绑定节点上的 Device Plugin 完成具体的设备分配和环境变量注入容器启动时通过 runtime hook 挂载 DCU 设备、注入 ROCm 环境变量。这个分层最大的好处是解耦平台只关心用户意图调度器只关心资源匹配节点只关心设备分配。每一层都可以单独升级、单独排障。3.2 镜像封装与运行时环境准备在平台层看到的镜像仓库里每种 DCU 相关的镜像都有一个显式的 ROCm 版本标签。这块的规范特别重要因为 DCU 的 ROCm 版本如果和宿主机驱动不一致轻则容器内无法调用 DCU重则直接 panic。我们现在的规范是在基础镜像里锁定 ROCm 版本并且通过平台侧的镜像构建流水线做版本校验不允许用户从任意基础镜像自由构建。具体封装步骤可以这样操作从官方源拉取与宿主机驱动匹配的 ROCm 基础镜像验证容器内能否正常执行rocm-smi确认设备可见确认/dev/dri设备节点和libdrm库均正常再叠加应用层依赖例如 Python 环境、PyTorch 的 DCU 版本最后做一次的端到端验证例如跑一个矩阵乘法或模型推理用例。提示不要使用 Docker Hub 上非官方维护的 ROCm 镜像。海光 DCU 的运行时库和 AMD 官方有差异用错镜像等于所有底层全错。4. 整卡与共享两种模式的具体配置与注意事项4.1 整卡分配最简单也是最快见效果的模式整卡分配的逻辑是让每个 Pod 独占一张物理卡。对于显存占用较大的模型比如 70B 级别的 DeepSeek 模型整卡模式通常是第一选择。在 Device Plugin 的配置文件中将cardsPerReplica设为 1在 Pod 的资源声明中添加类似cambricon.com/dcu: 1的字段根据实际设备插件名调整调度器会把 Pod 调度到有可用整卡的节点上。这里有一个容易忽略的细节DCU 的显存通常包含 HBM 和高带宽内存两部分整卡分配时需要注意把统一的资源上限设为整卡显存大小不能只算 HBM。不同型号卡的显存配置有差异需要以厂商规格为准。比如某型号 DCU 标称 32GB 显存实际可用可能因为 ECC 开启而略低资源声明时最好留一部分余量避免 Pod 启动后 OOM。4.2 共享模式如何安全地让多个 Pod 共用一张卡共享模式解决的是利用率问题。尤其是推理场景下一个小模型模型根本用不满整卡算力如果每个副本都独占一张卡成本就上去了。共享方案下可以看到明显提升。实现上需要注意两件事显存隔离和算力隔离。显存隔离相对简单在分配时通过环境变量指定每颗 DCU 使用的显存上限。这里一个关键点是设置正确的环境变量。在容器内要读取这些环境变量确保运行时正确应用显存限制。算力隔离比较微妙。DCU 的算力隔离在不同架构上力度不一样有的只做时间片轮转有的依赖底层 MPS 类机制。时间片方案简单但会出现一个 Pod 打满算力时其他 Pod 延迟升高的情况。如果对稳定性有要求应该采用有 QoS 保障的隔离方案确保关键任务不受干扰。在我的实践里一个比较稳妥的共享策略是在线推理任务设置显存硬上限和算力软上限离线训练任务使用低优先级配额避免互相挤占。这一步需要调节底层运行时的相关参数需要模拟真实负载来反复测试不能按照经验值直接拍脑袋。4.3 共享模式的资源声明与调度亲和性共享模式下资源声明的写法看起来和整卡差不多但平台侧的语义不同。整卡模式下1 代表一张完整物理卡共享模式下1 可能代表一个虚拟卡实例不同的虚拟卡实例可以落在同一张物理卡上。我会建议在调度策略中增加物理卡维度的亲和性。比如两个互相协作的 Pod如果放在同一张物理卡上数据交换速度快很多如果是为了容灾就应该打散到不同物理卡。CubeStudio 的调度器可以通过 node affinity 和 pod affinity/anti-affinity 实现这两种策略的组合。注意共享模式务必要做充分的基准测试。不同负载模型下的性能表现差异很大不要轻信纸面上的隔离参数。例如跑 DeepSeek 模型时同一个物理卡上同时有几个并发推理请求时延和吞吐的变化需要提前摸清。5. 两种 vDCU 虚拟化方案的拆解与对比5.1 虚拟化层的出现动机整卡和共享解决了能不能用能不能分的问题但生产环境还需要解决怎么隔离怎么保证性能的问题。这就是 vDCU 虚拟化存在的意义。vDCU 不是简单的资源配额还包含设备生命周期管理、性能隔离、故障隔离等内容。打个比方共享模式只是在一个房间里拉了几道帘子vDCU 则是切成了多个真正的隔间每个隔间有独立门锁、水电表。5.2 以硬件辅助为主 vDCU 方案当前落地的 vDCU 方案里一个方向是在硬件层面提供了地址转换和隔离能力让多个虚拟设备直接映射到物理设备的不同资源分区。它的特点是隔离性较高一个 vDCU 的异常不会影响到同卡上的其他 vDCU性能损耗低近乎物理卡直通配置相对简单在平台侧创建 vDCU 池用户申请时直接指定。但这类方案通常要求物理卡本身支持 SR-IOV 或者类似的硬件虚拟化能力如果部署规划里采购的卡型号不支持就没法用。5.3 以软件切分为主 vDCU 方案另一类是纯软件切分的 vDCU通过设备插件加运行时 hook 实现对设备资源的逻辑分割。它不依赖硬件虚拟化特性任何支持共享的 DCU 都能用。实现上更接近 GPU 生态中常见的显存限幅 算力配额模型。它的优点是兼容性好老卡新卡都能跑缺点是隔离性较弱极端情况下一个 Pod 的非法操作可能导致同卡其他 Pod 异常。在这类方案的部署中我会建议增加监控告警持续关注同卡 Pod 的运行状态。5.4 选型建议与成本考量评估维度硬件辅助型软件切分型隔离强度高中性能损耗低中硬件要求高需支持对应特性低所有型号通用运维复杂度中需要规划资源池低配置灵活适用场景生产级多租户开发测试或资源紧张场景我的实际建议是在有条件的生产集群优先用硬件辅助型的 vDCU尤其是在多团队共享、SLA 要求高的场景里。软件切分型适合作为补充在硬件资源不足时弹性使用。两条路线可以并行形成完整的资源供给体系。6. DeepSeek 部署实操从模型下载到服务发布6.1 模型选型与资源配置预估DeepSeek 系列模型有不同规模从 7B 到 70B 甚至 MoE 架构的更大模型都有。部署之前先把资源账算清楚避免模型拉下来后发现显存不够。以 7B 模型为例FP16 精度下权重文件大小约为 14GB加载到显存后再加上 KV Cache 和运行时开销实际占用大概 18~22GB。如果使用 INT8 量化显存占用会明显降低。对于 32GB 显存的 DCU单卡部署、单实例的方式是可行的。对于 70B 级别的模型单卡跑不了需要把模型划分到多卡上。海光 DCU 的集合通信库在张量并行场景下的表现直接决定了模型能跑多快模型并行时建议优先选择同机多卡减少跨机通信的开销。配置建议如下模型并行度根据模型大小算7B 用 1 卡70B 至少 4 卡起步服务副本数根据 QPS 预估建议先用 1 个副本压测再决定是否扩容vDCU 虚拟化如果单个服务用不满一张卡可以考虑把多个服务合到一张卡上。6.2 推理服务镜像构建与启动参数下面是一个实际可用的 Dockerfile 片段基于 ROCm 基础镜像FROM hub.cube-studio.io/rocm/dcu:6.2.0 RUN apt-get update \ pip install --no-cache-dir vllm-ascend COPY model_worker.py /app/ CMD [python, /app/model_worker.py, --model, /models/deepseek-7b, --tensor-parallel-size, 1]这里特别需要注意vllm-ascend这类 DCU 适配的加速框架不建议使用通用 vLLM 的 ROCm 版本直接跑。不同框架的算子优化差异非常大跑同一个模型的吞吐量可能差好几倍。启动参数里tensor-parallel-size要跟分配的 vDCU 数量对齐。如果底层用共享模式同一个 Pod 拿到多个卡实例这个值可以大于 1但前提是这些卡实例在物理上分布合理跨 NUMA 节点会带来额外延迟。6.3 通过 CubeStudio 发布服务的完整操作流在 CubeStudio 平台上发布一个 DCU 推理服务的流程大致如下在模型服务模块创建服务选择镜像和版本声明资源类型为DCU选择 vDCU 池或整卡模式设置资源规格例如 1 个 vDCU32GB 显存配置服务端口和健康检查路径例如/health提交后平台会自动完成调度、分配、启动、注册的全部流程通过平台提供的内部域名访问或者配置 Ingress 暴露。整个过程中用户体验已经非常接近使用 NVIDIA GPU 的水平这也是平台层适配的重要价值。用户不需要关心所在的是哪台物理节点、卡是否被别的任务占用只需要声明需求其余由平台处理。6.4 性能验证用真实压测数据说话服务上线后我会建议完成一次相对完整的压测后再对外释放流量。用一个简单的脚本记录 DeepSeek 推理的响应时间和并发表现import requests, time, concurrent.futures URL http://model-service:8000/v1/chat/completions DATA {model: deepseek-7b, messages: [{role: user, content: 你好}]} def test_once(_): t0 time.time() requests.post(URL, jsonDATA, timeout30) return time.time() - t0 with concurrent.futures.ThreadPoolExecutor(max_workers8) as pool: r list(pool.map(test_once, range(64))) print(fmean: {sum(r)/len(r):.3f}s, p95: {sorted(r)[int(len(r)*0.95)]:.3f}s)压测要注意区分纯模型推理耗时和整体链路耗时。整体链路包括网络传输、token 解析、模型推理如果发现时延偏高需要逐步拆解定位是网络问题还是模型推理问题。在 DCU 平台上的经验是模型推理耗时通常占大头网络和框架开销如果优化得好占比可以压得很低。不同的接入方式例如使用 vLLM 的 continuous batching对吞吐量的影响也很大实测下来可以比 naive 方式提升数倍。6.5 常见故障显存溢出的排查链路部署过程中最常遇到的就是显存溢出。这里给出一个完整的排查思路而不是直接给答案因为你环境里的具体情况需要自己确认第一步确认模型声明的显存上限是多少和实际峰值占用是否匹配第二步检查是否开启了 ECCECC 开启会降低可用显存第三步确认 KV Cache 是否配置了足够的上限默认配置可能会占满全部显存第四步看是否同时启动了多个 Worker多个进程叠加导致显存翻倍。大多数显存溢出的案例排到最后不是模型权重装不下而是辅助组件如 KV Cache、推理框架的缓存池、多个 Worker 进程把显存吃满了。把这几项指标都监控起来问题就能快速收敛。7. 部署过程里绕不开的坑实测踩过的问题清单7.1 驱动与 ROCm 版本错配的迷局第一次部署时最容易栽跟头的地方就是版本错配。DCU 的驱动和 ROCm 运行时之间耦合非常紧密。如果宿主机驱动版本是 5.x而镜像里是 6.x 的运行时大概率会出现莫名其妙的算子错误显存申请失败反而是较为温和的表现。定位手段是先在宿主机直接跑一次rocm-smi确认驱动侧没问题再进入容器内跑同样的命令逐步缩小范围。经验法则是无论什么时候都先从厂商官方兼容性列表找一个经过验证的组合然后在所有节点上保持一致。7.2 内核模块与容器 runtime 的不兼容海光 DCU 的驱动是内核模块方式加载的如果节点做过内核升级而驱动没跟着重新编译就会出现设备节点在但调用失败的诡异现象。排查命令包括lsmod | grep drm、dmesg | grep -i dcu、lspci | grep -i display。如果发现内核版本变了最快的解决方法是卸载驱动重新安装不要试图热补丁。7.3 Device Plugin 健康检查机制导致的资源黑洞用了 Device Plugin 之后有一个坑如果健康检查不完善某张卡挂了kubelet 依然会把它上报为可用资源Pod 被调度上去之后直接启动失败甚至反复 CrashLoopBackOff。生产环境要重点关注这个机制建议部署一个额外的监控脚本定期检查 DCU 的rocm-smi返回发现异常后手动驱逐相应节点上的 DCU Pod。7.4 共享模式下的算力干扰问题共享模式下多个 Pod 共用一张卡算力干扰几乎必然存在。之前实测过一个场景两个推理服务共享同一张卡低峰期时各跑各的没问题高峰期会同时看到 token 生成速度下降一半以上。这不是 bug而是算力隔离策略没有划分好。解决方案是根据业务优先级把高优任务放到独立的 vDCU 池里低优任务放到可抢占的资源池里用队列机制做缓冲。8. 对 CubeStudio 海光 DCU 适配方案的综合评价从整个接入过程来看CubeStudio 在海光 DCU 的适配上是下了功夫的。设备插件的稳定性和 CRD 调度的完整性都做到了生产可用的程度。镜像构建、模型服务发布、资源管理这些高层能力补齐了原生 Kubernetes 在 DCU 支持上的缺失。不过也要客观看待不足。当前文档数量相比 NVIDIA 生态还是偏少很多细节需要自己去源码里确认。适配版本的更新速度也比较快隔几个月看 API 可能就有变化。建议在引入新版本前先在一个小集群上做完整验证确认无回归错误后再推全量。另外建议关注社区用户反馈很多真实场景下的问题是最新文档都尚未覆盖的例如挂载多张 DCU 时的排序、共享模式下显存回收的时序等等。这些都需要持续跟进并根据自身环境进行针对性优化。9. 多模式并存的资源规划经验最后一块经验是资源供给的规划。一个集群中会同时存在整卡、共享、vDCU 三种模式因为它们面向的任务类型不同。我的经验是把资源池分为三个层次整卡池承接大模型训练和超大模型推理共享池承接单卡跑不满的小模型推理和开发测试任务vDCU 池承接需要隔离性且资源消耗中等的生产级任务。三个池子独立规划容量动态调整比例。根据团队实际需要可以定期根据资源水位进行扩容或缩容比在一个池子里多模式混跑更容易排查问题。这个思路在海光 DCU 和 NVIDIA GPU 环境中都切换使用过表现都比较稳定。对于正在规划 DCU 接入的朋友我的建议是在上线前先花一周时间把压测体系建立起来用数据支撑你的容量规划和模式选择而不是靠感觉来拍板。有了基准数据后续扩容、调优、排障都会顺畅很多。