一题一页 · 技术方法 · 也叫 国产化适配、信创适配

为什么大模型换一块国产芯片,就不能直接跑了?

同一个大模型换一块芯片就跑不起来,因为芯片下面那层软件不一样。适配就是把这层软件补齐、对齐、调快的工程活。

先看懂

技术方法
国产芯片适配
把模型从英伟达卡搬到国产卡上跑
不是改模型,是补它下面那层软件

此刻在看:静态解释,这一页的 4 个部分都是这一种。

主张依据 3 类:官方文档、公开报道与实践记录、编辑解释。

核实状态:这一页没有需要核实的结论,所以这一维是空的。

三个维度分别看:演示方式、主张依据、核实状态

演示方式

表示此刻展示方式,不是准确性等级。

  • 顶部三秒卡 静态解释
  • 举例与能/不能三栏 静态解释
  • 主张与依据 静态解释
  • 展开后的正文与关系说明 静态解释

主张依据

可多选,每种都有实际引用;「本站实验」需有记录。

核实状态

附范围、时间及必要原因,不等于全页绝对正确。

这一页没有需要核实的结论,所以这一维是空的——不会因为它挂着论文就替它标一个「已核对」。

举个例子

一份在英伟达卡上跑通的代码,搬到昇腾卡上改一行设备名。它不会直接跑起来,通常先卡在版本、再卡在算子、再卡在精度。

它能
  • 让已有模型在不同厂商的芯片上运行,不需要重新训练
  • 通过补算子、换数字格式、调显存策略把性能拉近
它不能 / 不是
  • 改不了芯片本身缺的能力,只能绕
  • 跑通不等于跑对,也不等于跑得快,这是三件事
  • 一次适配的结果不能自动迁移到别的模型或别的芯片型号
想看细节再点开

它到底难在哪

一句话:模型是通用的,模型下面那层软件不是。

大模型本身只是一堆数字和一串计算步骤,不认哪家的芯片。但这串计算步骤要落到硬件上,中间隔着一层厚厚的软件:算子库、图编译、显存管理、通信库。这层软件在英伟达那边被打磨了十几年,主流开源框架长期把它当默认路径,本站没有统计过具体比例。换一块芯片,这层要重写一遍。

四个坎,按遇到的顺序

版本。 驱动、固件、软件栈、框架插件、Python,五个版本要互相对得上。对不上的表现往往不是清晰的报错,而是莫名的崩溃。多份实践记录都把这一步列为最耗时的环节。

算子。 模型用到的某个数学动作,这层软件里还没有实现,或者实现了但很慢。前者报错,后者不报错,只是慢。

数字格式。 新模型越来越多用低精度格式发布权重,比如 FP8。芯片不支持这种格式,就得先把整份权重转成支持的格式。FP8 每个数占 8 位,BF16 每个数占 16 位,所以权重占的字节数翻倍。要注意翻倍的只有权重这一项:显存里还有激活值、KV 缓存、临时缓冲和框架自己的开销,总占用不会按同一个倍数走,具体多少取决于部署方式,本站没有实测。即便如此,权重通常是最大的一块,本来刚好装得下的模型可能就装不下了。

精度。 跑通之后还要验证算得对不对。做法是拿同一份输入,在两边逐层比对输出,看余弦相似度和误差。这一步经常发现某个算子实现有细微差别,累积到最后输出就变了样。

为什么这件事值得关心

不是因为技术新奇,而是因为它决定了一个很实际的问题:一个国家的 AI 应用,能不能不依赖单一供应商的芯片。这层软件的成熟度,比芯片的纸面参数更能说明进展到了哪一步。

它和其他概念的关系

  • 运行时依赖CANN昇腾这一侧的适配工作主要发生在 CANN 这层
  • 运行时依赖算子(Operator)补算子、调算子是适配里最花人力的部分

谁指向了这个词

  • ← 是……的组成部分CANN国产芯片适配的工作,大部分发生在这一层
  • ← 是……的组成部分算子(Operator)适配工作里最花人力的部分,就是补算子和调算子

看它发生

教学脚本 约 4 分钟
为什么大模型换一块国产芯片,就不能直接跑了?
换块芯片,模型就跑不起来
你的代码 PyTorch 翻译层 芯片 模型是通用的,它下面这层翻译软件不是。换芯片,换的是这一层
教学简化模型:场景按剧本逐屏播放;终端输出与四块面板里的版本号、算子个数、通过层数与余弦值都是按公开实践记录编写的示意终端输出、报错信息,以及右边四块「坎」面板里的全部数字(版本号、算子个数、通过层数、余弦相似度),都是按公开实践记录编写的示意,不是某一次真实运行的日志或实测值
你看到的(终端)
还没运行
幕后:这一步卡在哪
还没开始
你把在英伟达卡上跑通的代码原样搬过来,只改了一个词。
第 1 步 / 7

按暂停会把这一步的文字整段显示出来。这段字本来就是预先写好的,逐字出现只是展示方式,不是模型正在生成。 键盘:焦点在这个实验里时,← → 切换步骤,空格 播放或暂停。

此刻在看:教学脚本,这一页都是这一种。

主张依据 3 类:官方文档、公开报道与实践记录、编辑解释。

部分核对 核实状态:部分核对 · 核于 2026-09-07。

三个维度分别看:演示方式、主张依据、核实状态

演示方式

表示此刻展示方式,不是准确性等级。

  • 分步场景:换块芯片,模型就跑不起来 教学脚本
    教学简化模型:场景按剧本逐屏播放;终端输出与四块面板里的版本号、算子个数、通过层数与余弦值都是按公开实践记录编写的示意

主张依据

可多选,每种都有实际引用;「本站实验」需有记录。

核实状态

附范围、时间及必要原因,不等于全页绝对正确。

  • 部分核对
    本站核对这条结论: 核的范围:四个坎的存在与先后顺序对照三份第三方的公开实践记录与一份官方发布说明核过,其中官方发布说明本次未取到正文,读到的是搜索结果片段;面板里的版本号、算子个数、通过层数与余弦值是编写的示意,没有对照任何一次真实运行
    这一页没有跑过任何一块 AI 芯片,本站真正跑过并逐字粘贴的只有第 3 级那个精度对齐脚本
这个动画没有说的事
  • 终端输出、报错信息,以及右边四块「坎」面板里的全部数字(版本号、算子个数、通过层数、余弦相似度),都是按公开实践记录编写的示意,不是某一次真实运行的日志或实测值
  • 这些示意数字只表示「这一步会看到哪一类东西」,不能拿去引用;本站真正跑过并逐字粘贴的只有第 3 级那个精度对齐脚本
  • 具体型号支持哪些数字格式、缺哪些算子,随版本变化很快,以官方资料为准
  • 这里展示的是昇腾这条路线的共同流程;其他国产芯片的软件栈名字和细节不同
这一场戏的说明

这个单元把「大模型的国产芯片适配」拆成四个坎。它不讲芯片参数,只讲工程师实际会撞上的东西。看完之后,你应该能说出:为什么这件事难的不是模型,而是模型下面那层软件。

这个实验解释了哪些词

改一改

自己动手 · 约 15 分钟
说了这么多原理,实际落地时到底改了什么、看到了什么?
三行改动,四个坎,一个能跑的脚本
不是两块真实芯片的实测,是代码模拟

想自己动手,看这个 前四步要有卡才能复现,最后的精度对齐脚本任何电脑都能跑

此刻在看:历史记录展示 + 教学脚本 + 静态解释——4 个部分各自标着自己的那一种,没有一个徽章能概括整页。

主张依据 3 类:公开报道与实践记录、本站实验、编辑解释。

作者已逐字核对 核实状态:作者已逐字核对 · 核于 2026-09-08。

三个维度分别看:演示方式、主张依据、核实状态

演示方式

表示此刻展示方式,不是准确性等级。

  • 正文解读 静态解释
  • 迁移过程的示意代码与示意终端输出 教学脚本
    教学简化模型:前五步的代码与终端输出按公开实践记录编写,是这一步会看到哪一类东西的示意,不是某一次真实运行的日志
  • 可下载的 align_check.py 教学脚本
    教学简化模型:脚本在一台机器上用代码模拟出「参考实现」与「被测实现」,不是两块真实芯片的对比
  • 逐字粘贴的运行输出 历史记录展示
    教学简化模型:这段输出来自上面那个代码模拟的网络,跑的是真程序,量的不是两块真实芯片
    「简化」说的是模型简化,这一块此刻仍然在真的算。

主张依据

可多选,每种都有实际引用;「本站实验」需有记录。

核实状态

附范围、时间及必要原因,不等于全页绝对正确。

  • 作者已逐字核对
    本站核对这条结论: 核的范围:bf16 舍入用位运算、frexp 与 Fraction 三条路互相对齐;三种情况的输出由 tests/demo/test_align_check.py 的 12 组断言核对;在作者记录过的 arm64 macOS 环境逐字比对,其他平台仅允许情况三的 1-余弦在已证明的 8 ulp 求和噪声范围内变化,前提是 CPython 3.12 及以上
    verified 只表示作者真的运行并逐字粘贴(D9);这是一台机器上用代码模拟出来的对照,不是两块真实芯片的实测
这个实验现在就能运行 第 6 步只需要 python3,不需要任何 AI 芯片,也不用装任何库 下载脚本
  1. 起点:一段在英伟达卡上跑得好好的代码

    一个最小的推理脚本。它在英伟达卡上没有任何问题。

    python
    import torch
    from transformers import AutoModelForCausalLM, AutoTokenizer
    
    name = "your/model"
    tok = AutoTokenizer.from_pretrained(name)
    model = AutoModelForCausalLM.from_pretrained(
        name, torch_dtype=torch.bfloat16
    ).to("cuda").eval()
    
    ids = tok("今天天气很好,我们去", return_tensors="pt").to("cuda")
    with torch.no_grad():
        out = model.generate(**ids, max_new_tokens=16)
    print(tok.decode(out[0]))

    这一步是标准写法,没有跑过,仅作为迁移的起点。

  2. 改动本身只有三行

    装上厂商的 PyTorch 适配插件,导入它,然后把设备名从 cuda 换成 npu。看上去就完了。

    diff
    + import torch_npu          # 厂商提供的 PyTorch 适配插件
      import torch
      from transformers import AutoModelForCausalLM, AutoTokenizer
    
    - ).to("cuda").eval()
    + ).to("npu").eval()
    
    - ids = tok(..., return_tensors="pt").to("cuda")
    + ids = tok(..., return_tensors="pt").to("npu")

    torch_npu 是昇腾侧的 PyTorch 插件,代码仓库见页尾来源。改动确实就这么少,问题都在后面。

  3. 第一个坎:它不会直接跑起来

    第一次运行,报错往往指不到真正的原因。

    bash
    python3 run.py
    示意输出,不是真实运行
    Traceback (most recent call last):
      File "run.py", line 9, in <module>
        out = model.generate(**ids, max_new_tokens=16)
    RuntimeError: ACL stream synchronize failed, error code: 507011

    报错说的是底层运行时同步失败,但真正的原因通常是版本不匹配。这类报错信息是这条路上最典型的体验。

  4. 所以先对版本,这一步最费时间

    驱动、固件、软件栈、PyTorch 插件、Python,五个版本要互相对得上。

    bash
    npu-smi info                    # 看卡和驱动
    cat /usr/local/Ascend/ascend-toolkit/latest/version.cfg
    pip show torch torch_npu | grep -E "Name|Version"
    示意输出,不是真实运行
    driver     : 24.1.rc3
    firmware   : 7.5.0.1
    toolkit    : 8.0.RC2          <-- 插件要求 8.0.RC3
    Name: torch      Version: 2.1.0
    Name: torch_npu  Version: 2.1.0.post6

    多份公开实践记录都把版本匹配列为最易出错的环节,见页尾来源。

  5. 第二个坎:算子缺失长什么样

    版本对上之后,可能撞到模型用了这块卡还没实现的算子。

    bash
    python3 run.py
    示意输出,不是真实运行
    NotImplementedError: The operator 'aten::_scaled_dot_product_flash_attention'
    is not currently implemented for the NPU device.

    这类问题有明确报错,反而好办。更麻烦的是有实现但很慢,不报错,只是慢,只能靠逐层测时间去找。

  6. 第四个坎:精度对齐。这一步你现在就能跑

    前面几步需要真的有卡(第三个坎是数字格式,在场景那一页)。但最后这一步的方法本身,在任何一台电脑上都能演示。下面这个脚本在**一台机器上用代码模拟**三条被测路径:一条只把矩阵乘的输入舍入到 bf16 表示、一条把 layernorm 的方差分母写错成 n-1、一条直接把参考输出整体乘以 1.5。它不是两块真实芯片的对比,也没有真实硬件的 bf16 内核;跑的是同一份 Python 代码,差别都是代码里人为加进去的。

    bash
    curl -O https://你的站点/demo/align_check.py
    python3 align_check.py
    真实运行输出
    精度对齐:同一份输入,参考路径和 3 条被测路径差多少
    这是什么  一台机器上用代码模拟的对照,不是两块真实芯片的对比
              bf16 只对矩阵乘的输入做表示舍入,乘法与累加仍是双精度,不是硬件 bf16 内核
              余弦相似度按六位小数显示,1.000000 是显示值,不表示完整精度下相等
              门槛随张量尺度、层深和任务变,没有单一指标或统一阈值能判断所有算子
    参数      8 层 · 维度 64 · 4 行输入 · 随机种子 0 · 余弦门槛 0.999 · 缩放反例 ×1.5 · layernorm 的 eps 1e-05
    输入      random.Random(0):按顺序先生成 8 层 64×64 权重(高斯,均值 0、标准差 64^-0.5),再生成 4×64 输入(高斯,均值 0、标准差 1)
    参考计算  参考路径是同一份代码在 Python float(IEEE 754 双精度)下跑出来的输出,不是另一块芯片的输出,也不是更高精度的真值
    显示舍入  余弦相似度按 6 位小数显示,其余三列按三位有效数字的科学计数法显示;「1-余弦」那一列专门给出六位小数遮掉的部分
    指标口径  最大绝对误差 = max|a-b|,带量纲,随张量整体尺度一起变
              均方根误差 = sqrt(mean((a-b)²)),带量纲,不被单个离群点主导
              相对均方根误差 = ‖a-b‖₂ ÷ ‖a‖₂,无量纲;被测 = 参考 × c 时精确等于 |1-c|
    可复现    固定种子、不测耗时。作者在一台 arm64 macOS 上逐个试过 6 个 CPython:
              3.12~3.14 与页面上贴的那份逐字节相同;3.9~3.11 只有情况三的「1-余弦」那列不同
              (1e-16 量级),因为 CPython 3.12 起浮点 sum() 改用了补偿求和。
              情况三的真值是 0,那一列上的非零全是求和方式带来的舍入噪声。换一种 CPU 架构没有试过。
    
    【情况一 · 只有低精度输入表示(bf16 舍入),算子没写错】
      两侧输入舍入到 bf16 表示后再做同一次乘加,累加仍是双精度
      层   余弦相似度      1-余弦   最大绝对误差    均方根误差   相对均方根误差  余弦判定
    -------------------------------------------------------------------------------------
       1     0.999997   2.789e-06      7.264e-03     2.362e-03        2.362e-03      通过
       2     0.999994   6.018e-06      1.373e-02     3.469e-03        3.469e-03      通过
       3     0.999989   1.141e-05      1.922e-02     4.777e-03        4.777e-03      通过
       4     0.999982   1.834e-05      2.103e-02     6.056e-03        6.056e-03      通过
       5     0.999977   2.346e-05      2.526e-02     6.850e-03        6.850e-03      通过
       6     0.999959   4.078e-05      3.392e-02     9.030e-03        9.031e-03      通过
       7     0.999963   3.723e-05      3.316e-02     8.629e-03        8.629e-03      通过
       8     0.999957   4.282e-05      3.111e-02     9.254e-03        9.254e-03      通过
      余弦判定(门槛 0.999):8/8 层通过
    
    【情况二 · 算子写错了:方差除以 n-1 而不是 n】
      layernorm 的方差分母写成 63 而不是 64,其余一模一样
      层   余弦相似度      1-余弦   最大绝对误差    均方根误差   相对均方根误差  余弦判定
    -------------------------------------------------------------------------------------
       1     1.000000   4.441e-16      1.539e-02     7.843e-03        7.843e-03      通过
       2     0.999998   1.693e-06      1.183e-02     8.054e-03        8.055e-03      通过
       3     0.999995   4.753e-06      1.505e-02     8.423e-03        8.423e-03      通过
       4     0.999992   7.717e-06      1.836e-02     8.765e-03        8.765e-03      通过
       5     0.999987   1.324e-05      2.046e-02     9.369e-03        9.369e-03      通过
       6     0.999979   2.148e-05      2.265e-02     1.020e-02        1.020e-02      通过
       7     0.999979   2.069e-05      2.439e-02     1.013e-02        1.013e-02      通过
       8     0.999971   2.869e-05      2.738e-02     1.088e-02        1.088e-02      通过
      余弦判定(门槛 0.999):8/8 层通过
    
    【情况三 · 缩放反例:把参考输出整体乘以 1.5(人为构造,不是芯片会犯的错)】
      被测输出 = 参考输出 × 1.5,方向一个字没变
      层   余弦相似度      1-余弦   最大绝对误差    均方根误差   相对均方根误差  余弦判定
    -------------------------------------------------------------------------------------
       1     1.000000   0.000e+00      9.812e-01     5.000e-01        5.000e-01      通过
       2     1.000000   0.000e+00      8.756e-01     5.000e-01        5.000e-01      通过
       3     1.000000   0.000e+00      9.860e-01     5.000e-01        5.000e-01      通过
       4     1.000000   0.000e+00      9.322e-01     5.000e-01        5.000e-01      通过
       5     1.000000   1.110e-16      9.827e-01     5.000e-01        5.000e-01      通过
       6     1.000000   0.000e+00      9.021e-01     5.000e-01        5.000e-01      通过
       7     1.000000   0.000e+00      8.206e-01     5.000e-01        5.000e-01      通过
       8     1.000000   1.110e-16      8.281e-01     5.000e-01        5.000e-01      通过
      余弦判定(门槛 0.999):8/8 层通过
    
    三张表放在一起看:余弦判定在 3/3 种情况里都是「全部通过」,
    包括第二种真写错的算子和第三种纯缩放——余弦只看方向,看不见整体缩放。
    带量纲的最大绝对误差和均方根误差看得见缩放,但数值随张量尺度一起变,换个模型、换一层就要换门槛;
    无量纲的相对均方根误差在情况三里精确等于 |1-1.5| = 0.5。
    所以真实的对齐脚本会同时看几个指标、逐层看趋势,而不是宣布某一个指标配某一个阈值就能定所有算子的对错。

    这段输出实际跑出来: 在哪里跑的:作者本机,arm64 macOS,CPython 3.14.7 你现在打开这一页不会有任何程序被执行。

    这 64 行是本页作者在 2026-09-08 用 CPython 3.14.7(arm64 macOS)真实运行得到的,逐字粘贴。脚本用固定随机种子、不测耗时,可复现有边界:作者在同一台机器上试过 6 个 CPython,3.12~3.14 逐字节相同,3.9~3.11 只有情况三那列「1-余弦」不同(1e-16 量级,CPython 3.12 起浮点 sum() 改用了补偿求和)。换一种 CPU 架构作者当时没有试过。`tests/demo/test_align_check.py` 会重跑脚本;在这组已记录环境中逐行逐字比较,其他平台仅允许情况三该列在 8 ulp 内变化,其余字段不放过,所以门禁要求 CPython ≥ 3.12。

  7. 读懂这三张表,这才是重点

    情况二是算子真的写错了,方差除以 n-1 而不是 n。但它第 1 层的余弦相似度按六位小数显示是 1.000000,比情况一还漂亮,八层全部「通过」。原因是余弦相似度只看方向不看长度,而这个 bug 在每一行里恰好是一个标量缩放。情况三是把这件事推到极端的缩放反例:直接把参考输出整体乘以 1.5,方向一个字没变,余弦八层全过,相对均方根误差却精确等于 0.5。

    两件事要一起记住。第一,`1.000000` 是**六位小数的显示值**,不表示完整精度下相等——所以表里专门有一列「1-余弦」,情况二第 1 层是 4.441e-16,情况一第 1 层是 2.789e-06。第二,只拿余弦相似度当验收标准,会把一个真写错的算子放过去,还给它打满分。

  8. 所以真实的对齐脚本会同时看几个指标

    至少要有一个对缩放敏感的指标,比如最大绝对误差、均方根误差或相对均方根误差,并且要看它随层数怎么变化。带量纲的那两个随张量尺度一起变,所以门槛不能跨模型、跨层照抄;无量纲的相对均方根误差在「被测 = 参考 × c」时精确等于 |1-c|。

    python
    def check(ref, dev):
        return {
            "cosine":   cosine(ref, dev),          # 只看方向,对正比例缩放不敏感
            "cos_gap":  1 - cosine(ref, dev),      # 六位小数显示遮掉的那部分
            "max_abs":  max_abs_diff(ref, dev),    # 带量纲,随张量尺度一起变
            "rmse":     rmse(ref, dev),            # 带量纲,不被单个离群点主导
            "rel_rmse": rel_rmse(ref, dev),        # 无量纲,被测 = 参考 × c 时等于 |1-c|
        }
    # 逐层跑一遍,看几个指标一起怎么变;门槛随张量尺度、层深和任务定,
    # 没有哪一个指标配哪一个固定阈值能判断所有算子是对是错。

    这就是「跑通不等于跑对」在代码里的样子。这里给的是口径,不是验收线——同一批数字整体放大 1000 倍,余弦和相对均方根误差一个字不变,最大绝对误差会跟着放大 1000 倍。

这个脚本的说明

这一页是「国产芯片适配」的第三级。前面的卡片告诉你它是什么,场景演了一遍它怎么发生,这里给你能真正动手的东西。

第 1 到 5 步是迁移的真实样子,需要有卡才能复现,所以那些输出都标了「示意」。第三个坎(数字格式)没有单独一步,它在场景那一页。第 6 步不需要任何卡,你现在就能跑,输出是真实的。

第 6 步能证明什么、不能证明什么,写在这里:它证明的是这套指标在同一份数字上分别看见了什么——一台机器上用代码模拟出来的三条被测路径,跑的是同一份 Python 代码。它不是两块真实芯片的对比,bf16 那一路只对矩阵乘的输入做表示舍入、乘加仍是双精度,所以它也不是硬件 bf16 内核的行为。表里的 1.000000 是六位小数的显示值,旁边那列「1-余弦」才是它遮掉的量级。这里的余弦门槛 0.999 只是这个玩具配置的演示门槛:门槛随张量尺度、层深和任务变,没有单一指标或统一阈值能判断所有算子是对是错。

还有一件事顺便被这个脚本自己演示了。作者把它在同一台机器上的 6 个 CPython 里各跑一遍:3.12~3.14 与上面那 64 行逐字节相同,3.9~3.11 只有情况三的「1-余弦」那一列不同,差在 1e-16 量级——因为 CPython 3.12 起浮点 sum() 改用了补偿求和。情况三的真值本来就是 0(被测 = 参考 × 1.5,方向完全一致),所以那一列上的非零全是求和方式带来的舍入噪声。换句话说:连「同一份代码、同一台机器、只换了解释器版本」都会让最后几位不一样,这正是精度对齐这件事存在的理由。换一种 CPU 架构作者没有试过。

查证据

这一场戏的结论

换芯片难的不是模型,是它下面那层翻译软件:跑通、跑对、跑得快是三件事。

成立条件
  • 终端输出与四块「坎」面板里的数字都是按公开实践记录编写的示意
  • 这里展示的是昇腾这条路线的基本流程,别的国产芯片软件栈细节不同
这个脚本的结论

在 8 层 × 维度 64 的代码模拟网络上,余弦相似度全部「通过」,最大绝对误差 1.539e-02 才露出写错的算子。

成立条件
  • 8 层 × 维度 64 的代码模拟网络
  • 那个写错的算子把方差除以 63,正确的分母是 64
  • 一台机器上用代码模拟出来的对照,不是两块芯片的对比
「为什么大模型换一块国产芯片,就不能直接跑了?」的完整结论:必要条件、指标口径与已归档的旧结论

看完你应该能说出

模型本身一个字都没改。难的是它下面那层翻译软件:版本要对齐、算子要补齐、数字格式要转换、精度要逐层比对。跑通、跑对、跑得快是三件事。

成立条件:少一条,上面那句话就不成立
  • 终端输出与四块「坎」面板里的数字都是按公开实践记录编写的示意
  • 这里展示的是昇腾这条路线的基本流程,别的国产芯片软件栈细节不同
这条结论的边界
  • 具体型号支持哪些数字格式、缺哪些算子随版本变化很快,以官方资料为准
  • 这一页没有测量迁移前后的吞吐或延迟,「跑得快」只是四个坎里的第四个名字
核验
部分核对 · 本站核对这条结论: · 核的范围:四个坎的存在与先后顺序对照三份第三方的公开实践记录与一份官方发布说明核过,其中官方发布说明本次未取到正文,读到的是搜索结果片段;面板里的版本号、算子个数、通过层数与余弦值是编写的示意,没有对照任何一次真实运行(这一页没有跑过任何一块 AI 芯片,本站真正跑过并逐字粘贴的只有第 3 级那个精度对齐脚本)
证据
  • 本站条目 sources/vllm-ascend-pitfalls
  • 本站条目 sources/deepseek-fp8-bf16
  • 本站条目 sources/ascend-910b-practice
  • 本站条目 sources/vllm-ascend-docs
「说了这么多原理,实际落地时到底改了什么、看到了什么?」的完整结论:必要条件、指标口径与已归档的旧结论

做完你应该能说出

迁移的代码改动可能只有三行,工作量全在后面:对版本、补算子、转格式、验精度。验精度这一步,在这个 8 层 × 维度 64 的代码模拟网络上,一个真写错的算子(方差除以 63 而不是 64)在 8 层里余弦相似度全部「通过」,第 1 层的六位小数显示值还是 1.000000;同一批数字的最大绝对误差 1.539e-02 才把它露出来。

成立条件:少一条,上面那句话就不成立
  • 8 层 × 维度 64 的代码模拟网络
  • 那个写错的算子把方差除以 63,正确的分母是 64
  • 一台机器上用代码模拟出来的对照,不是两块芯片的对比
这条结论的边界
  • 同机 6 个 CPython 里 3.9 到 3.11 有 8 行输出不同(1e-16 量级),页面这一份的前提是 CPython 3.12 及以上
  • 没有单一指标或统一阈值能判断算子是对是错,这一页只演示余弦相似度会漏掉什么
  • 前五步是按公开实践记录编写的示意,可运行的是第 6 步
这条结论引用的数

上面那一栏是整条结论的公共条件;下面每一行另有自己的口径,所以单独摘走一行也带着口径。

这个数是什么数值它在什么范围内成立
代码模拟网络的层数8 层
每层维度 64,权重与输入都是脚本里固定种子生成的,不对应任何真实模型
第 1 层余弦相似度的六位小数显示值1.000000
六位小数的显示值,不能读成两边完全一致;后面几位的差别就藏在这个显示精度以下
同一批数字的最大绝对误差1.539e-02
情况三那一批数字上的最大绝对误差;它随张量尺度变,换一批数字这个数就不作数
核验
作者已逐字核对 · 本站核对这条结论: · 核的范围:bf16 舍入用位运算、frexp 与 Fraction 三条路互相对齐;三种情况的输出由 tests/demo/test_align_check.py 的 12 组断言核对;在作者记录过的 arm64 macOS 环境逐字比对,其他平台仅允许情况三的 1-余弦在已证明的 8 ulp 求和噪声范围内变化,前提是 CPython 3.12 及以上(verified 只表示作者真的运行并逐字粘贴(D9);这是一台机器上用代码模拟出来的对照,不是两块真实芯片的实测)
证据
  • 仓库内记录 docs/execution/ALIGN_EVIDENCE.md
  • 本站条目 sources/vllm-ascend-pitfalls
脚本版本
public/demo/align_check.py@sha256:d3c2df1da471433f3ff98b8b9c0c41b376b91993399e5aa50d0d7aac4227fc8c

主张与依据

  • 第三方实践记录指出,适配中最易出错的环节是环境配置:驱动、固件、CANN 或 DTK、PyTorch、Python 的版本需要严格匹配。 [ vllm-ascend-pitfalls ]
  • 第三方实践记录指出,DeepSeek 官方发布的权重采用 FP8 格式,在昇腾 910B 上需要先转换为 BF16 才能使用。具体型号的格式支持情况应以官方资料为准。 [ deepseek-fp8-bf16 ]
  • 公开资料显示,通过 vLLM 的昇腾后端,DeepSeek 系列的大规模混合专家模型已可运行在昇腾算力上。官方发布说明本次未直接取到正文。 [ vllm-ascend-docsdeepseek-fp8-bf16 ]

档案目录

  1. 发布或实践记录简体中文

    vllm-ascend-pitfalls

    vLLM-Ascend 实战指南:从环境部署到性能调优的完整避坑手册

    出版方/保存方
    CSDN
    原页语言
    简体中文
    本站访问
    核对程度:没有记录,说不出读到哪一层没有记录具体读到哪一层,因此不能把这条记录当作全文核对。
    访问结果:正常取到

    第三方实践记录:驱动、固件、CANN、PyTorch、Python 版本严格匹配,是最易出错环节。

    打开原始来源
  2. 发布或实践记录简体中文

    deepseek-fp8-bf16

    华为昇腾 910B×8 部署 DeepSeek 实战记录

    出版方/保存方
    博客园
    原页语言
    简体中文
    本站访问
    核对程度:没有记录,说不出读到哪一层没有记录具体读到哪一层,因此不能把这条记录当作全文核对。
    访问结果:正常取到

    第三方实践记录:DeepSeek 官方权重为 FP8,910B 不支持,需转为 BF16。属于个人实践,具体型号支持情况以官方为准。

    打开原始来源
  3. 官方文档简体中文

    vllm-ascend-docs

    vLLM Ascend 发布说明(官方文档)

    出版方/保存方
    vLLM 项目官方文档
    原页语言
    简体中文
    本站访问
    核对程度:未取到原文,经转述

    搜索结果给出的页面标题与片段;发布说明原文一个字都没读到
    访问结果:没取到2026-09-07 直接抓取返回 HTTP 429,发布说明的正文一个字都没取到;搜索结果里的页面标题与摘要片段,以及可以自行核对的 URL;引用它的两条主张都已写明是转述

    vLLM 昇腾后端的官方发布说明。2026-09-07 直接抓取返回 429,页面内容经搜索结果转述,未逐字核对原文。

    打开原始来源
  4. 发布或实践记录简体中文

    ascend-910b-practice

    华为昇腾910B国产化适配深度解析:从CANN算子到vLLM实践

    出版方/保存方
    知乎
    原页语言
    简体中文
    本站访问
    核对程度:没有记录,说不出读到哪一层没有记录具体读到哪一层,因此不能把这条记录当作全文核对。
    访问结果:正常取到

    第三方实践记录:CANN 分层结构带来的双层排错、版本匹配与显存管理差异。属于个人经验,非官方口径。

    打开原始来源
  5. 代码仓库简体中文英文

    torch-npu-repo

    Ascend/pytorch(torch_npu)代码仓库

    出版方/保存方
    Gitee · Ascend
    原页语言
    简体中文 · 英文
    本站访问
    核对程度:没有记录,说不出读到哪一层没有记录具体读到哪一层,因此不能把这条记录当作全文核对。
    访问结果:正常取到

    PyTorch 的昇腾适配插件,提供 npu 设备后端。版本需与 CANN、驱动匹配。

    打开原始来源