海光 BW1000 DCU 初探:从硬件特性、软件栈到开发实践的初学者指南

发布时间:2026/7/18 21:09:57
海光 BW1000 DCU 初探:从硬件特性、软件栈到开发实践的初学者指南 初学者首次接触海光BW1000需要了解哪些内容以及如何使用这块国产DCU记录时间2026-07-162026先导杯基于国产DCU上Qwen大模型推理加速后记这篇东西其实算是比赛结束后补的一次作业。我在参加比赛的时候成绩并不是很好在那段时间大部分时间都在研究模型、推理框架以及各种参数当时基本是遇到一个问题就先解决一个问题服务能跑起来以后再继续处理下一个环节。等到事情结束回过头来看发现了一个问题代码在BW1000上运行很多次但是对这张卡却了解不多。公开参数并不难找但真正开始开发以后遇到的问题往往不在参数表里。为什么在 PyTorch 中还要使用.cuda()环境中的 torch 可以更新吗数据从 CPU 移动到 GPU 多快一张 64GB 显卡为什么放进去一个模型还是会显存不足所以我后来把环境重跑一遍再补几组比较简单的测试。例如做矩阵乘法、CPU 和 DCU 之间拷贝以及简单显存读写操作等。首先是一个简单的环境描述我的这个环境状态良好并且效果良好在大规模矩阵中FP16、FP32、FP64 的 GEMM 比较接近公开资料展示的速度大约为 91.5%、93.1% 和 87.6%而简单的读写操作根据其传输的数据量来估计也在开放显存带宽的八成左右至少在这些基本任务上这张卡以及相关软件栈都是正常工作的。DCU是什么DCU可以看作是针对通用并行计算进行加速的设备。CPU负责系统的管理和一些复杂的分支操作等而DCU更擅长处理大量的相同计算任务例如矩阵乘法、张量运算、深度学习训练及推断、数值模拟、科学计算等。刚开始我看这个软件栈也是比较混乱后来简单画出来如下图所示就方便多了。应用代码 ↓ PyTorch / vLLM / TensorFlow / 科学计算程序 ↓ 适配版框架、BLAS、DNN、通信库 ↓ HIP、编译器、运行时、性能工具 ↓ DTK 与驱动 ↓ BW1000 DCU根据海光公开资料 DCU 是基于 GPGPU 架构、兼容类 CUDA 环境的通用协处理器同时提到了双精度计算、高带宽内存和并行处理能力。1“类CUDA”这3个字很容易让读者产生一种误解既然接口相似那么原来的代码可以直接搬过来使用吗并非如此普通的PyTorch模型如果是使用常用的算子则可以较顺畅但是如果涉及到自定义CUDA扩展、Triton kernel、flash-attn或者经过大量修改的推理引擎等则不能有这种想法。接口相似只是一方面的问题在底层实现以及版本是否匹配才是更重要的问题。BW1000 的公开参数主要看下边几项模力方舟官网公布的BW1000参数有64GB HBM2e、1.6TB/s显存带宽、约300W典型功耗以及支持FP16、FP32和FP64等多种精度。而参考计算能力为FP16 480TFLOPS、FP32 60TFLOPS、FP64 30TFLOPS并且说明不支持FP8。2项目公开资料数据实际开发中应该关心什么存储64 GB HBM2e是否能放下所有模型权重、KV cache以及临时空间显存带宽1.6TB/s访存型算子是否会由于等待数据而被阻塞FP16480 TFLOPS训练、推理以及混合精度计算FP3260 TFLOPS一般运算以及对精度有一定要求的应用场景FP6430 TFLOPS科学计算仿真双精度线性代数等。FP8不支持需要选择量化方案或者使用FP8 KV cache 在此之前需要进行检查。典型功耗约 300 W根据设备所承受负载情况进行参考使用不能作为业务测试依据64GB显存看似很大但是显存并非是被模型权重所占用。权重只是一部分在进行推理过程中还会存在KV cache、workspace、框架缓存以及编译生成的buffer等而在跑图捕获时还会有新的内容。再加上分配器预留以及内存碎片等问题的存在实际上可用的空间远远小于看上去那么大。我在做长上下文推理任务中明显感觉到显存参数不能设置到最大值。短请求可以正常启动但经常有长请求、warmup以及并发oom的情况发生。留有一定的冗余虽然看起来很保守但是实际上却更节省时间。理论算力也差不多。GEMM 能跑高说明这条路线可行但是实际模型中还有 attention、归一化、采样、CPU 调度、网络服务以及各种小算子最终得到 tokens/s 并不能简单地用 TFLOPS 来换算。问题一升级 torch我已经拿到环境有 DTK、HIP、PyTorch 和 vLLMPyTorch 接口仍然是熟悉的写法torch.cuda.is_available()返回也同样是True。当时看到这个情况也是放松了警惕以为与普通的 CUDA 环境区别不大。但随着我敲下这行代码出现了个问题pipinstall--upgradetorch我所在环境中的torch带有dtk2604标记vLLM为0.18.1das.dtk2604。这表示这个包已经与当前DTK进行了适配在使用来自公网PyPI的标准PyTorch覆盖之后虽然版本号可能变化但是设备无法被检测到更严重的是可能会出现ABI、算子编译以及运行时的问题。类似的也会出现在 Triton、flash-attn 自定义扩展等地方。很多时候出现问题并不是因为代码本身有误而是以往的传统开发能否真正适用于新环境也就是说像这样每个包都可以正常安装但是彼此之间却不能兼容。解决这些问题相当耗费时间错误提示处不一定就是问题发生的地点。OpenCloudOS 的一个 BW1000 部署示例使用了驱动 6.3.16 和 DTK 25.04.2并且用hy-smi、rocm-smi查看设备。3而这一组版本在我自己的机器上并不是这样这也提示我们在网上查找资料时要留意版本号是否相同。我这台机器比赛环境的情况后面的所有测试都是在这个环境中进行。表格较长但是版本号还是要保留过几个月再看能够知道自己当时跑的是哪个版本。项目当前环境操作系统Ubuntu 22.04.5 LTS内核5.10.134-17.1.3.sga8.x86_64CPUHygon C86处理器2路lscpu显示128个逻辑处理器系统内存约 503 GiBDCU单卡设备名为BW显存hy-smi显示 65520 MiBPyTorch 显示约 63.98 GiBCompute Unit80ISAgfx936驱动6.3.31-V1.5.0ahy-smi1.24.0编译日期 2026-03-23DTK/opt/dtk-26.04-DCC2602-0317HIP6.2.0-0Python3.10.12PyTorch2.10.0pip包带有dtk2604标记vLLM0.18.1das.dtk2604还有一些比较底层的信息设备挂载在0000:55:00.0内核驱动为hycuNUMA node 是 2PCIe 状态是 32.0 GT/s、x16。rocminfo显示有 80 个 CU、wavefront size 64、最大主频 1500 MHz。空闲状态下温度约为 50-55 摄氏度功率约为 71-78 瓦。日常检查主要用下面这些命令久够用uname-acat/etc/os-release lscpufree-hhy-smi hy-smi-ahy-smi--showmeminfovram hy-smi--showtopohy-smi--showdriverversionrocminfo hipcc--versionpython3-mpip list|grep-E\dtk|torch|vllm|deepspeed|hip|rocm|tritonPyTorch 侧再跑个最小检查importtorchprint(PyTorch:,torch.__version__)print(Available:,torch.cuda.is_available())print(Device count:,torch.cuda.device_count())iftorch.cuda.is_available():propstorch.cuda.get_device_properties(0)print(Device:,props.name)print(Memory GiB:,props.total_memory/1024**3)print(Compute units:,props.multi_processor_count)在我这台机器上这里返回的是True设备名为BW尽管接口仍然使用torch.cuda但在内部实现上是基于 DCU 的适配层。矩阵乘法测试看看三种精度比赛后我做的第一个测试是矩阵乘法。矩阵乘法是一个非常经典的并行计算的例子代码少跑得快同时可以比较 FP16, FP32 和 FP64。测试用方阵大小由 2048 增加至 12288。每组预热 10 次测量 30 次在开始以及结束时调用torch.cuda.synchronize()函数。张量创建尽可能不在计时范围内。吞吐量取值为2 × N³。这里使用的是框架层测试而非专门针对某一家厂商的测试工具特别是像2048这种亚毫秒级的结果由于主机计时以及同步的开销较大在此更多是观察趋势。精度矩阵规模平均时间ms中位时间ms中位吞吐TFLOPS峰值显存MiBFP1620480.100.09183.5164FP1640960.480.48288.27160FP1681923.643.64301.91544FP16122888.458.45439.181184FP3220480.410.4141.6496FP3240962.592.5853.20288FP32819219.9519.9355.161056FP321228866.4966.4755.832336FP6420480.770.7622.51160FP6440965.565.5524.75544FP64819245.8245.9023.952080FP6412288141.19141.2126.284640FP16 从 8192 到 12288 提升显著。按表里的最好结果算FP16 是 439.18 TFLOPS约为公开参考值 480 TFLOPS 的 91.5%FP32 是 55.83 TFLOPS约为 60 TFLOPS 的 93.1%FP64 是 26.28 TFLOPS约为 30 TFLOPS 的 87.6%。这些对于我来说已经足够有说服力的结果。虽然不能保证所有的工作负载都能达到90%但是至少可以说明目前使用PyTorch与DTK结合可以充分利用矩阵计算的能力。而FP64的表现也给我留下了深刻的印象在支持半精度AI的同时双精度的科学计算也是有意义的。数据搬运然后是pageable host memory以及pinned host memory上H2D(Host to Device)、D2H(Device to Host)目标张量预先申请在复制完毕之后进行同步。如表所示方向Host 内存数据量MiB中位时间ms估算带宽GB/sH2Dpageable645.2412.81D2Hpageable642.0133.34H2Dpinned641.4446.68D2Hpinned641.4446.52H2Dpageable25620.2613.25D2Hpageable2567.2936.84H2Dpinned2565.5548.34D2Hpinned2565.6747.37H2Dpageable102485.6712.53D2Hpageable102427.5838.93H2Dpinned102422.1048.58D2Hpinned102422.5747.58pinned H2D 基本能稳定在 4749 GB/spageable H2D 只有 1213 GB/s。这也是为何在训练或者推理循环中反复搬运小张量得不偿失。即使DCU计算速度非常快但是每一遍都需要等待CPU传递数据最终还是白白浪费时间。怎样合理使用CPU以及DCU计算能力也是在工程上需要考虑的问题。在资源调度上是否能解决这个问题这方面的知识我了解尚浅如果有了解的朋友可以在评论区讨论另外.item()、.cpu()等函数也要注意它们也有可能造成同步在计时脚本中如果不考虑这个问题则测得的时间实际上是任务提交的时间我是之前在查看结果时常常忽略这一点后来我统一了所有的地方进行同步。显存读写然后是D2D copy以及一个最简单的FP32 vector add。在此之前需要知道 D2D copy 如果用“复制的数据量 ÷ 时间”得到的是有效复制吞吐但是从 HBM 角度看它发生了读取源张量一次写入目标张量一次因此总的流量应乘以 2。vector add 是 CAB即两次读取一次写入因此用三个张量的数据量来衡量。测试单个张量或有效数据规模估算 HBM 总流量中位时间ms有效复制吞吐GB/s估算 HBM 流量带宽GB/sD2D copy256 MiB512 MiB0.44614.861229.72D2D copy1024 MiB2048 MiB1.62661.251322.50D2D copy4096 MiB8192 MiB6.37674.441348.88FP32 vector add256 MiB768 MiB0.66—1224.89FP32 vector add1024 MiB3072 MiB2.53—1273.38FP32 vector add4096 MiB12288 MiB10.01—1287.68根据HBM读写流量计算D2D约为1.23~1.35TB/s,vector add为1.22~1.29TB/s约等于公开1.6TB/s参考值的80%左右。Qwen3.5-27B 推理任务微基准跑起来很快真实推理不是。我在一个 Qwen3.5-27B 长上下文任务中使用了 vLLM, Triton/HIP kernel, KV cache 以及torch.compile。有一回的日志显示中,模型加载耗时约 374s,torch.compile耗时约 209s, profiling 和 warmup 大约也是 208s, engine init 记录了一个较长的时间即 436s可能是我改毁了一些东西。这些阶段是有包含关系不是简单的相加。但是感觉很直观的一点是一个启动需要等待很久的时间。如果稍微改动一些内容就会导致重新编译那么半天都未必能够跑完一轮大部分时间都是花费在加载以及warm-up上。这也是我后来更加重视编译缓存的原因。第一次启动时间和稳定状态下的请求时间要区别对待第一个请求不能算作正常的吞吐量在进行 A/B测试的时候一方面命中缓存另一方面又重新编译结果无法进行对比。显存规划也是一样在长上下文中模型权重并不是唯一的部分还有KV cache、workspace、图捕获以及临时缓冲区都需要空间如果设置gpu_memory_utilization过大对于短期请求可能是可以接受的但是对于较长的请求或者是warmup就会出现问题在实际开发中应该先留有余地把服务稳定下来之后再去逐步提高这个值。写在最后BW1000 给我的总体感受是硬件基本功扎实在 FP16、FP32、FP64 大矩阵运算上均达到公开参考结果水平在框架层面的显存带宽也得到了良好体现。64GB 显存对于大模型以及科学研究非常有利。开发上真正需要适应的是软件栈。DTK、HIP、适配版 PyTorch 及上层框架是整体版本对上可以很流畅版本混用会非常麻烦排查问题。这并非 BW1000 所特有在国产异构环境下目前更多需要开发者自己做记录与核对。我这次做的都是很基础的测试离完整评价一张计算卡还差得很远。多卡通信、真实训练吞吐、不同模型的推理表现、自定义 kernel 优化等都没有涉及。但是对初学者第一次使用 BW1000 而言先了解机器的状态如何、公开的数据是什么样的、程序容易出现的问题是什么相信这份测试报告应该能起到一定的作用最后感谢阅读参考资料海光信息技术股份有限公司《首次公开发行股票并在科创板上市招股说明书申报稿》“海光 DCU”相关章节上海证券交易所https://static.sse.com.cn/stock/disclosure/announcement/c/202111/001043_20211108_ALLG.pdf ↩︎模力方舟《海光 GPU》包含 BW1000 公开规格、HIP、DTK 和适配版 PyTorch 环境说明https://ai.gitee.com/docs/compute/clusters_gpu/hygon_gpu ↩︎OpenCloudOS《基于 OpenCloudOS 的海光 DCU 部署实践》包含 BW1000、驱动、DTK 和环境检查示例https://docs.opencloudos.org/OC9/ai-deployment/GPU-optimization-practice/hygon-deployment/ ↩︎