带新人这件事做久了会发现,从 N 卡阵营转到海光 DCU,卡住人的往往不是代码,是名词。新同事第一次上机,周围人聊天里蹦出 DTK、HCU、RCCL、gfx928,每个都得停下来问一句"这是什么";查一个报错,搜出来全是 AMD ROCm 的帖子,又不确定能不能照抄。这不是知识量的问题,是词汇表的问题——两套硬件世界的概念一一对应,缺的只是一张翻译表。
这份问答就是把这张翻译表拆成了十八个最常被问到的词条。背景先交代清楚:一台 8 卡海光 DCU 服务器,DTK 26.04,PyTorch-DCU 搭配 DTK 适配版 vLLM 和 triton 3.x,下面每个词条都来自这台机器上实际跑通的迁移工作,不是文档抄录。读法也简单:见到什么查什么,不用背。
## 一、整套工具链叫什么
**问 1:DCU 机器上装的 DTK,相当于 N 卡那套里的哪一样?**
答:相当于"CUDA Toolkit + cuDNN + NCCL 的总和",不是其中某一项。它是个全家桶:编译器 hipcc、运行库、通信库 RCCL、算子库 MIOpen、性能工具、llvm/clang 工具链,全在这一套里。所以装在 `/opt/dtk-26.04/` 下面会同时看到 `llvm/`、`hip/`、`lib/` 这些目录,占的磁盘也比"一个运行时"该有的大得多。把它理解成"装上就能跑 GPU 代码的运行时",后面每一步都会困惑。另外记住一个细节:版本号跟着安装路径走,`/opt/dtk-<版本>/` 这种形态自带版本信息,机器上要换版本、要并存,脚本里改的就是这一行路径。
**问 2:报错里写着 HIP error,是不是卡坏了?**
答:不是。HIP 只是接口层的名字,不是硬件名;报 HIP error 只说明错误发生在 GPU 调用这条路径上,具体原因得看错误码和上下文。它和 N 卡上报 CUDA error 是一回事,别被陌生的前缀吓住。
**问 3:nvcc 对应的是什么?**
答:hipcc。编译器命令换了名字,参数风格类似,跟着工具链一起装在 DTK 里。
## 二、卡、互联和架构号
**问 4:系统里的"卡"叫什么?HCU 是什么意思?**
答:HCU 0-7。HCU = Hygon Compute Unit,就是"一张加速卡",hy-smi 输出里看到 HCU 0-7,按 gpu0-7 理解不会错。唯一要小心的是别拿 AMD CPU 背景里的 compute unit(SM 级别的计算单元)来套——同一个词在两个语境里差了一个量级。
**问 5:有 NVLink 吗?卡和卡之间靠什么连?**
答:海光自己的方案叫 HCCS,作用等同 NVLink,但名字和拓扑查看工具都不同。nvidia-smi topo 那套命令在这里没有对应物,直接照搬会扑空。
**问 6:报错里频繁出现的 gfx926、gfx928 是什么?**
答:gfx 系列号,ROCm 世界通用的硬件标识,对标 N 卡上的 sm_89 这类架构号,triton 和编译器靠它定位目标硬件。看到报错里有 gfx 字样,说明这是编译器在说硬件语言,不是 Python 层的问题;反过来,N 卡那套 sm_ 前缀在 DCU 的报错里不会出现,一旦看到 gfx 就该切到 ROCm 语境去想。网上大量针对 gfx906、gfx928 的 triton 和编译器讨论,拿来对照 DCU 的问题往往一针见血。
## 三、库名对对碰
**问 7:NCCL 换成了什么?多卡训练代码要跟着改吗?**
答:换成了 RCCL,可以理解成同一个角色的不同演员——all-reduce、all-gather、broadcast 这些集合通信原语,语义、参数、超时行为基本一致,NCCL 的调优经验大半可以照搬,NCCL 里踩过的超时、环拓扑那套思路在这边照样用得上。代码上唯一要注意的是下面这一条。
**问 8:既然底层是 RCCL,backend 参数是不是该写成 'rccl'?**
答:千万别改。PyTorch 的 backend 按注册名查找,DCU 版 torch 在编译时把 RCCL 注册成了 `nccl` 这个名字——参数写 `'nccl'`,底下实际跑的就是 RCCL。写成 `'rccl'` 启动直接报"不支持的 backend"。见过有人核对依赖清单时"顺手"改了这一处,结果整个分布式启动卡在第一步。名字是接口约定,不是实现指认,想确认底下是谁,看 DTK 装了哪个通信库就行,代码层不要动。
**问 9:cuDNN 和 flash-attention 有对应物吗?**
答:cuDNN 对应 MIOpen,卷积、RNN 这类算子的底层实现。flash-attention 有 DCU 移植版,但必须装 DTK 编译的版本,pip 直接装上游包是不行的。
**问 10:bitsandbytes、vLLM、transformers 这些库呢?**
答:三种待遇。bitsandbytes 没有等价物,多个版本都装不上,依赖它的 8-bit/4-bit 量化路线要整体换掉;vLLM 不能用官方 pip 包,得用 DTK 适配版 wheel,版本号自带厂商后缀,而且被锁在适配渠道里,别想着 pip 升到上游;transformers、accelerate 是同一套,直接用,代码几乎不用改。上层框架生态基本无损,缺口集中在底层加速库——这也是整个迁移里"翻译工作量"分布最不均匀的地方。
## 四、看得见摸得着的部分
**问 11:nvidia-smi 在这边用什么替?**
答:两个。rocm-smi 是通用查询工具,看显存、利用率、温度都行;hy-smi 是海光厂商工具,部分厂商私有信息只有它能看。分工上:两边都能看的通用项就用 rocm-smi,遇到通用工具查不到、或者要对账厂商口径的信息,再开 hy-smi。两个都留着,重要的数字两边交叉验证一遍更放心。
**问 12:容器里跑 DCU 程序,设备节点怎么挂?**
答:这是最容易照搬错的一处。N 卡的惯例是挂 `/dev/nvidia*` 加几个库目录,DCU 的用户态访问入口完全不同:`/dev/kfd`(计算框架设备)和 `/dev/dri/card*`(渲染节点)。启动参数里显式 `--device=/dev/kfd --device=/dev/dri`,再确认容器内用户对这两个节点有读写权限——挂载只是第一步,权限没跟上一样报找不到设备。挂完在容器里跑一次 rocm-smi,能看到卡才算直通成功。挂错了的症状很典型:宿主机一切正常,容器里 import torch 报找不到设备或 HIP 初始化失败。
**问 13:CUDA_VISIBLE_DEVICES 换成了什么?**
答:对应 HIP_VISIBLE_DEVICES,语义等价,shell 脚本里要改的就是这一类变量。
## 五、观念上的几句话
**问 14:torch.cuda.* 要不要全局替换成 torch.hip.*?**
答:一个字符都不用改。DCU 版 PyTorch 把 CUDA 的 API 命名原样保留了——名字叫 cuda,底下跑的是 HIP,这是一层历史包袱式的兼容设计;`torch.cuda.is_available()` 在 DCU 上返回 True 完全正常。改名只发生在更底层(编译器、通信库、驱动接口),Python 应用层感知不到。所以翻译的范围比想象中窄得多:要翻译的是名词和环境,不是代码。
**问 15:N 卡上那些"装完就不用管"的东西,DCU 上还用不用管?**
答:要管,而且要当成开机动作管。N 卡上工具链是空气:装完驱动和 CUDA,`import torch` 就能跑,路径自动可发现。DCU 上 DTK 装在 `/opt/dtk-<版本>/`,不 source 它的 env.sh 环境就不完整;编译类任务还要显式告诉编译器目标架构是哪个 gfx。环境变量在这里不是可选的调优项,是一等公民——选卡、找库、定架构,少了哪个都会在很深的地方炸出一个不相关的报错。所有脚本第一步固定 `source /opt/dtk-26.04/env.sh`,把它当成开机的一部分。
**问 16:import torch 正常,是不是就能开干了?**
答:还不能。就绪判据要从"import 成功"换成"编译成功":PyTorch 运行只依赖一部分库路径,而 triton 编译要找 clang、ld.lld 这些工具链,路径全靠 source env.sh 注入。跳过这一步,import 照样通,一跑 torch.compile 或 vLLM 的编译路径立刻崩,报错长得和"没装 triton"一模一样。固定动作是:source 完之后跑一段最简单的 triton kernel,通过才算环境就绪。
**问 17:搜不到 DCU 的解法时怎么办?**
答:把 ROCm 当第二关键词。DCU 的软件栈和 AMD ROCm 同源,ROCm 生态里积累的经验大部分直接适用;报搜不到的错加上 ROCm 去搜,命中率立刻上去。gfx 系列号的讨论同理,直接相关。
**问 18:第一次接手一台 DCU 机器,有没有一条最低限度的就绪检查?**
答:有,四步走完再开干。第一步 `source /opt/dtk-26.04/env.sh`,把工具链挂上;第二步 `hipconfig --version` 确认工具链应答正常;第三步 rocm-smi 确认 8 张卡都在、显存干净;第四步跑一段最简单的 triton kernel,通过才算编译链就绪。import torch 返回 True 只能算第一关,不能当就绪标准——原因见问 16。
最后把账算一下:从 N 卡换到 DCU,算法代码占的工作量大约 5%——`torch.cuda.*` 原样可用、transformers 直接复用,真正要动手改的算法代码少到可以忽略;80% 花在工程配置上——source 环境、换设备节点挂法、换适配版 wheel、绕开没有等价物的库,这些都不难,但每一个都是"不踩不知道"的知识,一张对照表省下的正是这部分时间;剩下 15% 是接受"CUDA 是默认值、HIP 是要配的"这个前提。一句话收束:换的不是编程方式,是默认值。这份问答存下来,下一个从 N 卡过来的同事,第一天就能听懂这里的语言。