尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

从CUDA到昇腾:DeepSeek适配背后的技术迁移之路

从CUDA到昇腾:DeepSeek适配背后的技术迁移之路 1. 假期里的这条消息为什么值得放下手里的瓜1.1 先还原一下发生了什么春节假期那几天我本来在乡下烤火刷手机结果技术群里突然炸了。DeepSeek 和华为两家趁着大多数人都在休假把一件对国内 AI 算力生态影响挺大的事往前推了一大步——DeepSeek 系列模型完成了对华为昇腾Ascend平台的深度适配并且不是简单能跑的那种适配而是从算子层到训练框架层做了系统性打通。结合华为这边 CANN 计算架构和 MindSpore 生态的持续迭代CUDA 国产替代这个喊了好几年的口号终于有了一个看得见摸得着的技术底座。我当时的第一反应是这事儿的象征意义和实际意义都很大但网上很多讨论都停留在华为牛DeepSeek 牛的情绪层面很少有人把技术路径拆开讲清楚。作为一个这几年一直在折腾 GPU 计算、也被 CUDA 生态绑得死死的开发者我觉得有必要把这里面的门道好好捋一捋——CUDA 到底凭什么这么难替代所谓替代替代的究竟是什么如果你现在手上有一批模型要迁移会碰到哪些具体的坑1.2 为什么说这是干成了一件大事说它大不是说华为昇腾的芯片性能突然超过了 NVIDIA 的旗舰卡——至少在通用计算峰值上还没有人能拍胸脯说全面超越。真正的大事在于过去 CUDA 的护城河不只是硬件性能而是整条软件栈从 GPU 驱动、底层的 PTX 指令集到 cuBLAS、cuDNN 这些计算库再到 PyTorch、TensorFlow 这些框架里的 CUDA 后端最后到 Millions 的开发者已经写好的 CUDA 代码。你要撬动这条链任何一个环节断了都白搭。DeepSeek 做的事情等于在模型这一层给出了一个高价值的示范案例一个大体量、高关注度的开源模型不依赖 CUDA 也能在国产芯片上顺利训练和推理。华为做的事情等于在工具链这一层把让模型跑起来所需的全部底盘补齐了。两件事合在一起才是完整的替代叙事。这比单纯发布一块新芯片要难得多因为你在和一个积累了十几年的生态对抗。2. CUDA 的护城河到底有多深2.1 CUDA 不只是GPU 的编程语言很多刚接触的同学会把 CUDA 理解成一种给显卡写代码的语言这个理解没错但远远不够。CUDA 是一个完整的并行计算平台它包含三层东西第一层是硬件抽象让你不用关心 GPU 内部到底有多少个 SM、寄存器怎么分配你只需要写内核函数让成千上万个线程并行执行第二层是高性能计算库比如做矩阵乘法的 cuBLAS、做深度学习加速的 cuDNN、做线性代数求解的 cuSOLVER这些库都是 NVIDIA 的工程师用汇编级优化一点点抠出来的同一个矩阵乘法你用现成库和自己手写性能差距可以到几十倍第三层是开发工具链包括编译器 nvcc、性能分析器 ncu/nvprof、调试器 cuda-gdb以及跟 PyTorch、TensorFlow 深度绑定的运行时。我经常用一个类比来解释这层关系CUDA 就像一个极其成熟的操作系统——不是 Windows 那种图形界面系统而是那种你看不见、但所有软件都跑在它上面的底层系统。你写 PyTorch 代码的时候torch.cuda.FloatTensor背后走的是 CUDA 的显存管理和内核调度你用torch.matmul它自动调到 cuBLAS 里那些手工优化的矩阵核函数。开发者平时根本感受不到 CUDA 的存在但一旦要换平台才发现自己写的每一行代码底下都垫着一层 CUDA。2.2 生态锁定的三个层次我这些年做 GPU 计算优化最大的体会是 CUDA 的锁定是分三个层次逐级加深的第一层是代码级锁定。只要你的项目里写过 CUDA kernel或者用到了 CUDA 特有的 API比如自管理显存、自定义 stream 并发那迁移的时候这些代码基本得重写。比较讽刺的是很多项目里的 CUDA 代码其实是当年从别人那儿抄来的或者是从 Stack Overflow 上拼出来的作者自己都不一定完全理解现在要重写难度直接拉满。第二层是库级锁定。就算你一行 CUDA 代码都没写过只要你的 PyTorch 模型用到了 cuDNN 里的卷积优化算法、或者通过 TensorRT 做过推理加速那你的性能基准就是建立在 NVIDIA 私有库的基础之上。换到别家芯片就算算子功能上等价性能也大概率会有差距因为别家没有积累十几年的调优经验。第三层是习惯级锁定这一层最隐蔽也最难破。所有 AI 开发者从入门第一天用的就是nvidia-smi看显存就是torch.cuda.is_available()判断环境就是 CUDA 版本和 PyTorch 版本要严格匹配这套玩法。你习惯了这套工作流之后换一个平台意味着所有肌肉记忆都要重来。我见过不少团队嘴上喊着要支持国产芯片真到迁移那天光是一个怎么查看昇腾 NPU 的算子执行耗时就能卡住一整天。3. 国产替代拆开来看技术路径到底是什么3.1 硬件层昇腾的达芬奇架构和 CUDA 的根本差异华为昇腾芯片用的是自研的达芬奇Da Vinci架构它和 NVIDIA 的 Ampere/Hopper/Blackwell 架构在设计哲学上有本质区别。NVIDIA 的思路是大规模通用并行几千个 CUDA core 齐刷刷发力适合各种形态的并行计算。达芬奇架构的核心是 AI Core每个 AI Core 内部有一个 Cube 单元专门做矩阵运算配合 Vector 单元做向量运算还有 Scalar 单元处理标量逻辑属于典型的面向 AI 计算做定制的设计。这个差异带来的直接后果是CUDA 代码里那种把问题拆成大量线程并行处理的写法在昇腾上不一定高效。昇腾的编程模型更强调我要算矩阵就直接喂给 Cube 单元数据搬运走专用的缓冲区。所以迁移不只是改语法而是要重新理解硬件的工作方式。我刚开始接触 CANN 的时候最大的不适应就在这里——我习惯了 CUDA 那种线程块 共享内存的心智模型到了昇腾上得换成token 流 数据搬运的思维这个转变需要一段时间适应。3.2 软件层CANN、MindSpore 和兼容层的三层结构华为在软件层构建的体系可以看成三层最底层是 CANNCompute Architecture for Neural Networks它的定位类似于 CUDA 的驱动加运行时。CANN 屏蔽了底层硬件的差异向上提供统一的算子开发接口和运行时管理能力包括内存管理、流管理、算子调度这些基础服务。昇腾上跑的模型最终都要落到 CANN 这一层。中间层是框架适配层。华为自己的 MindSpore 是原生支持昇腾的这也是为什么很多国产化项目直接选 MindSpore 的原因。但现实情况是AI 社区的主流框架是 PyTorch所以华为做了 PyTorch 的昇腾适配分支让大部分 PyTorch 代码能通过替换后端的方式跑在昇腾上。这些年华为对 PyTorch 适配的投入明显加大算子覆盖面越来越广已经有不少模型能做到改一两行配置就跑起来。最上层是模型层。DeepSeek 的适配工作主要发生在这里把模型的算子实现、分布式策略、混合精度方案针对昇腾硬件重新设计和验证。这层工作说起来轻巧实际工作量非常大。DeepSeek 这种大规模模型训练时要考虑张量并行、流水线并行、数据并行多种策略的组合每种并行策略对通信库的要求都不一样而昇腾的集合通信库 HCCL 和 NVIDIA 的 NCCL 在接口语义和性能特性上都有差异需要针对性地调。3.3 DeepSeek 的角色为什么模型方的适配这么关键很多人会问华为自己有 MindSpore为什么还非得 DeepSeek 来适配答案在于生态的势能。模型是 AI 生态里的头部应用一个明星模型选择跑在哪个平台会直接决定开发者跟不跟。DeepSeek 的开源模型在技术社区的使用量极大全球开发者每天用它在做推理、微调、二次开发。当这部分人发现我用 DeepSeek 模型可以直接在昇腾上跑不需要 CUDA那昇腾生态就不再是HW 的生态而是所有 DeepSeek 用户的生态。这就是我常说的应用反哺平台的逻辑。芯片再强没有头部应用在上面跑开发者没有动力迁移一旦有头部应用带头吃螃蟹迁移的试错成本就大幅下降了。DeepSeek 做这件事的意义比它单纯发布一个新模型版本要大得多——它等于在模型层给了整个生态一个可复制的迁移范本。4. 从 CUDA 迁移到昇腾实际操作要过哪些坎4.1 迁移第一步算子映射与重写我实际帮团队做过一次模型迁移把一套基于 PyTorch 的推荐模型从 CUDA 搬到昇腾上整个过程走下来第一个要面对的硬骨头就是算子映射。PyTorch 模型里的每个操作——卷积、矩阵乘、LayerNorm、Softmax、Attention——在 CUDA 后端有一个实现在昇腾后端是另一套实现。理想情况下你只需要把model.to(cuda)改成model.to(npu)剩下的框架帮你搞定。但现实往往没那么顺利一些算子比如某些自定义的 CUDA kernel昇腾上没有对应的原生实现要么用多个基础算子组合去模拟要么就得自己写 TBE 算子——这是昇腾的自定义算子开发方式类似于 CUDA kernel但语法和优化思路完全不同。我当时遇到的一个具体问题是模型里有一个自定义的融合算子把一个 GEMM 和一个 elementwise 的激活函数融合在一起以减少显存读写。这在 CUDA 上是很成熟的优化手段但昇腾的算子融合规则跟 CUDA 不一样强行按原来的逻辑组合反而性能更差。最后我是把融合拆开利用 CANN 提供的算子融合标记让它在底层自动融合效果反而更好。这个经验说明了迁移不是翻译而是重新优化。4.2 我踩过的坑精度对齐、性能调优、Debug 工具链第二个让我印象深刻的是精度对齐问题。同一套模型在 CUDA 上跑和昇腾上跑loss 曲线长得完全不同。这不是玄学而是两边的浮点运算顺序、混合精度策略FP16/BF16 的支持程度、梯度累积方式都有细微差别。特别是在混合精度这块NVIDIA 那边有成熟的 AMPAutomatic Mixed Precision机制昇腾上的混合精度实现逻辑不一样某些算子在 FP16 下的精度表现差异会比较大导致训练不稳定。我当时花了一整周时间排查一个诡异的现象模型在昇腾上 loss 早期降得飞快但到了一定程度就再也不降了。后来定位到是某个归一化算子在低精度下的实现精度不够换成 FP32 的计算路径就正常了代价是那个算子稍微慢一点。这种问题在 CUDA 上几乎不会遇到因为 NVIDIA 对每个算子的精度边界都做了严格验证而昇腾的算子精度边界覆盖还有不少盲区。选型的时候一定要留出精度调优的时间预算。第三个坑是Debug 工具链的成熟度差距。在 CUDA 上跑崩了有 cuda-gdb性能有问题有 ncu 可以做逐 kernel 分析显存异常有 compute-sanitizer 查越界。昇腾这边也有对应的工具比如 msprof、mindstudio但说实话流畅度和信息量跟 NVIDIA 工具链还有差距。特别是当你处理大规模分布式训练的时候通信瓶颈的定位工具会直接影响你的排查效率。我的建议是迁移团队的成员必须有一个是熟悉昇腾工具链的否则遇到问题会非常被动。4.3 哪些场景适合先迁移哪些先观望以我的经验现在这个阶段有几个场景非常适合先试水昇腾推理场景。尤其是批量离线推理对实时性要求不高、对吞吐量要求高昇腾的推理性能和性价比已经比较能打了。而且推理链路相对干净不涉及复杂的分布式训练策略。标准模型微调。比如用 DeepSeek-R1 做领域微调数据量不大、模型结构改动不大这类任务的迁移成本可控适合作为团队的第一个昇腾项目。新项目冷启动。如果你正好要训一个新模型没有历史包袱那可以直接考虑以昇腾为主要训练平台CUDA 作为备用对照。反过来暂时不建议迁移的场景包括已有的超大规模预训练任务迁移成本极高且分布式通信优化需要大量投入、重度依赖 NVIDIA 特定库比如 TensorRT 的量化工具链的项目、以及团队没有专职做底层优化的场景。对这些场景更务实的策略是双轨运行——CUDA 继续作为主力昇腾跑一个验证副本逐步积累经验。5. 对开发者来说接下来该做什么准备5.1 学习方法论不一定要立刻换但要开始懂我这几年的体会是技术选型最怕的不是选错而是完全没准备。对于 CUDA 开发者你不一定马上要切换到昇腾但至少应该开始了解几件事第一弄懂 CANN 的基本编程模型。不需要你马上写 TBE 算子但至少要知道昇腾的 AI Core 怎么工作、数据搬运和计算是怎么流水线化的。这决定了你未来评估性能问题时能不能用对的分析框架。第二学会看昇腾的算子支持列表。PyTorch 在昇腾上的算子覆盖是持续扩展的但总有一些边缘算子没覆盖到。你在设计模型结构的时候如果能提前避开这些算子迁移就会顺畅得多。我见过太多人把模型写完之后才发现某个自定义算子不支持被迫重构网络结构。第三把通信库的差异放在心上。分布式训练是迁移中最容易被低估的部分。NCCL 的环形 AllReduce 和 HCCL 的实现差异直接影响你在多卡训练时的扩展效率。建议找一份 HCCL 的文档通读一遍重点看它支持的集合通信原语和拓扑感知策略。5.2 给团队的建议小步试错双轨并行留好回退如果你是一个技术负责人我的建议非常朴素不要搞大爆炸式迁移。挑一个小模型、一条推理链路、一个非核心业务用一两个迭代周期把它完整跑通记录过程中的所有问题形成团队的迁移知识库。然后再逐步扩大范围。双轨并行的具体做法是代码层面尽量做好硬件抽象比如用 PyTorch 的 device 抽象把cuda和npu处理成配置项而不是写死在代码里。这样你在 CUDA 上开发的每一分积累未来都有可能无缝地平移到昇腾上。我见过很多团队早期图省事代码里写满了torch.cuda的硬编码等要迁移的时候才发现改起来像拆地雷。另外一定要留好性能基准。迁移前把模型在 CUDA 上的训练吞吐、推理延迟、显存占用全部记录成基准文档。迁移后逐项对比性能差距可以接受和性能差异背后的原因要分开评估——前者是结论后者是价值。有时候同样的模型在昇腾上慢不是因为硬件不行而是因为某个算子的实现方式不合理换一种写法就能追平。5.3 我在实际迁移中最后想分享的一点文章写到这里按照惯例应该做个总结但我不太想写那种展望未来的套话。我更想说的是这套迁移的事儿最关键的不是技术本身而是开始动手这件事。我见过太多讨论了大家在群里聊得热火朝天但真正去翻 CANN 文档、去跑第一个昇腾样例、去把自己的模型挪过去跑一遍的人少之又少。我自己第一次把 PyTorch 模型搬到昇腾的体验说实话并不愉快——环境配置就折腾了两天各种版本不匹配、算子不支持的报错接踵而来。但跨过那个坎之后再回头看我发现那些报错其实都是文档里写清楚的事情只是我一开始没花时间去看。当你真正跑通第一个模型的那一刻你会发现国产计算平台并没有想象中那么遥不可及。最后分享一个小技巧如果你打算开始尝试不要一上来就搞大模型。找一个小巧的、你特别熟悉的模型比如一个经典 CNN 或者在跑 DeepSeek 的蒸馏小模型把迁移流程完整走一遍。这个过程里你能把 CANN 的算子映射逻辑、混合精度的设置方式、甚至调试工具链的用法都摸熟之后再面对大项目就有了底气。技术选型的主动权永远是留给那些提前动过手的人的。
返回列表