深度解读 📅 2026-10-29 ✍️ MagicNetWorld 编辑部

GPU 做 prefill、NPU 做 decode:HAWK 如何让跨架构 KV 搬运接近 GPU 直连,在线服务输出吞吐差最高 7.88%(arXiv 2610.29873v2 精读)

把 prefill 交给 GPU、把 decode 交给 NPU,这套异构拆分卡在一个具体动作上:KV 缓存要从 GPU 显存搬到 NPU 内存。韩国电子通信研究院(ETRI)与佐治亚理工的 HAWK(arXiv:2610.29873;v1 2026-10-21、v2 2026-10-23,下文「论文」均指 v2 正文)用共享的 Linux RDMA 栈,加上「按目标布局分配 NPU 侧缓冲区」与「把布局变换拆两段、让传输顺手完成对齐」,在 4 张 A100 PCIe 40 GB 与 4 张 Tenstorrent p150a 加速卡组成的商用系统上,让这一路搬运的延迟接近 GPU 到 GPU 直连(本文按论文 Figure 9 归一化读数反算,1280 MB 处约 0.6%)。本文区分三个不可直接混用的能效口径:kernel 算力能效(TFLOPS 每 ASIC kW)、decode 相位能效(输出 token/s 每 decode 设备 ASIC kW)、全服务设备能效(输出 token/s 每 prefill 与 decode 全部设备 ASIC kW)。按论文 v2 正文口径、以 GG-Direct(GPU 到 GPU、RDMA 直连)为基线,在相同 90% SLO 达成条件下,Llama 3.1 70B 的输出吞吐分别比基线低 0.48%(Chatbot)与 7.88%(Summarization);全服务设备能效为基线的 1.26 倍与 1.15 倍;按论文所列设备价格计算的成本效率为基线的 2.03 倍与 1.88 倍(不等于服务器整机墙电功耗口径)。截至本文 2026-10-29 核验,arXiv 摘要页仍显示 v1 的 1.72 倍成本效率,与 v2 正文的 2.03 倍冲突。所有数字均为论文口径转述,本文没有实测。

KV 缓存PD 分离异构推理NPURDMA张量布局推理系统

除另行标注外,本文引用的外部事实与页面核验时点为 2026-10-29(北京时间);除另注版本外,下文「论文」均指 2026-10-23 发布的 arXiv:2610.29873v2 正文。文中凡出自论文、官方文档或一手材料的数字,一律用 [n] 标注编号;凡本文按公式自己算出来的数字,一律标「本文自行推导」并写清假设。本文没有任何端到端实测:没有 A100 集群,也没有 p150a 板子。所有吞吐、延迟、能效数字都是论文报告的数值转述,或按公开常量复算的量级。

一、先把结论说清:这篇论文修的是「搬运」,不是「算力」

一句话版本:prefill 和 decode 是推理的两个阶段,本文讨论的是把它们分别部署到 GPU 节点与 NPU 节点;把两段拆到两种芯片上并不难,难的是拆完之后那条「把 KV 缓存送过去」的通道。

不严谨的比方。一家工厂有两道工序:前段是把整块原料一次性切好(prefill,所有输入 token 一次性并行处理,是稠密矩阵乘),后段是逐个零件往外送(decode,一次只生成一个 token,是矩阵乘向量)。前段吃算力,后段吃内存带宽。GPU 擅长前段,NPU 擅长后段——论文开篇就是拿这个观察做动机 [1](论文署名:第一作者来自佐治亚理工,其余五位作者来自韩国电子通信研究院 ETRI,见论文首页)。

但如果前段在一号车间、后段在二号车间,中间就要有一条传送带把半成品送过去。这条传送带在本文里就是 KV 缓存从 GPU 显存到 NPU 内存的搬运。论文测下来,这条传送带如果走「先落到主机内存、再从主机内存搬出去」的老路,延迟是同构 GPU 直连的 1.83 倍到 5.25 倍(传输量 10 MB 到 1.2 GB,这是论文在 GPU 到 GPU 之间测的)[1]。而如果强行直连,又会撞上第二个问题:两块芯片对同一个张量在内存里怎么摆,意见不一致。

HAWK 这个名字是 Heterogeneity-AWare Key-Value transfer 的缩写 [1]。它做的事可以拆成三件,后文按顺序讲:给 NPU 也接上一个 peer memory client(让网卡能直接读写 NPU 设备内存)、按 NPU 的张量布局去分配 RDMA 缓冲区、把布局变换拆成两段让传输过程顺手完成对齐。

先说清楚这篇论文的边界,免得读者把结论放大:单一 NPU 平台(Tenstorrent p150a,即 Tenstorrent 的 NPU 加速卡型号)、单一模型(Llama 3.1 70B)、单一并行度(TP=4)、单一网络(200 Gbps HDR InfiniBand),没有跨平台验证,也没有开源代码(论文写「plan to release」)[1]。所以本文的定位是「把一个真实系统的机制拆开讲清」,不是「NPU 已经能替代 GPU」。

读这篇论文的建议顺序:先看论文 Table 1 的四个数(动机),再看论文 §4.2 那个 OOM 的反面教材(为什么难),最后看论文 Table 8 与 Table 9(收益怎么量、量出来是多少)。 三处看完,这篇论文的骨架就清楚了;其余章节都是这三处的展开与证据。

二、先算一笔账:一次请求的 KV 到底有多大

要判断「搬运」值不值得专门写一篇论文,第一步是把被搬的东西量出来。设模型有 LL 层、HkvH_{kv} 个 KV 头、每个头维度为 dd、每个元素占 bb 字节,则每 token、跨全部 L 层的 KV 占用是:

Skv=2⋅L⋅Hkv⋅d⋅bS_{kv} = 2 \cdot L \cdot H_{kv} \cdot d \cdot b

这里的 2 是 Key 与 Value 各一份。后文会区分三种体积:每 token 跨全部层的 KV(用来估算搬运量)、乘输入长度后的单请求 KV(用来对比传输时间)、模型权重(用来解释 decode 为什么容易被访存卡住)。代入 Llama 3.1 70B 的公开配置:L=80L = 80 层、Hkv=8H_{kv} = 8 个 KV 头(64 个查询头做 GQA 分组共享)、d=128d = 128(由 hidden size 8192 除以 64 个查询头得到)、b=2b = 2 字节(模型卡配置为 bfloat16)[3][4],得到:

Skv=2×80×8×128×2=327,680 字节=320 KiB≈0.3125 MiBS_{kv} = 2 \times 80 \times 8 \times 128 \times 2 = 327{,}680\ \text{字节} = 320\ \text{KiB} \approx 0.3125\ \text{MiB}

也就是说,在本文的 bf16 假设下,每多一个输入 token,跨全部层的 KV 就多 320 KiB。再把它乘上论文用的两种负载的输入长度(Chatbot 用 ShareGPT,均值 783 token、P90 899;Summarization 用 LongBench,均值 2186、P90 2860)[1],并除以 200 Gbps InfiniBand 的线速(200×109/8=25200 \times 10^9 / 8 = 25 GB/s):

Sreq=Skv⋅Lin,txfer=SreqBWS_{req} = S_{kv} \cdot L_{in}, \qquad t_{xfer} = \frac{S_{req}}{BW}
负载输入 token(均值 / P90)KV 体积(均值 / P90,MiB)线速下的纯传输时间(均值 / P90,ms)
Chatbot(ShareGPT)783 / 899244.7 / 280.910.26 / 11.78
Summarization(LongBench)2186 / 2860683.1 / 893.828.65 / 37.49

注:KV 体积与传输时间两列为本文自行推导(按上面两个公式、上面四个公开配置常量计算,未计入协议开销、序列化与布局变换时间,也未考虑 TP 分片后单卡只搬 1/4;论文的传输量扫描覆盖 10 MB 到 1280 MB)[1][4]。

这张表回答了两个直觉问题。第一,被搬的东西不是 KB 级,是几百 MiB 级,所以「搬运」在实践中绕不开。第二,纯传输时间是十毫秒量级,而论文设定的 TTFT SLO 是 2000 ms(Chatbot)与 15000 ms(Summarization)[1],看起来占比不高——问题在于 KV 搬运落在首 token 之前的关键路径上,它不占用算力,却直接推迟第一个 token。同样十毫秒,在部分批处理任务里可能不显著,放在 P90 首字延迟的预算里就要算账。

顺带记一个对不上的细节:论文说「10 MB 的传输量对应 64 个输入 token」[1]。按上面的推导,bf16 下 10 MB 只对应约 30.5 个 token;要凑到 64 个 token,每 token 得是 156 KB 左右,即每个元素 1 字节(FP8/INT8 量化的 KV)。论文没有说明 KV 缓存的数据类型(只写「保留 Tenstorrent 软件栈默认的混合精度配置」)[1],所以本文按 bf16 推导,并把论文那句括注列为口径未闭合项。

为什么 decode 天生被带宽卡住:一个算术强度就够

这一小节要解释的是「为什么同样的芯片,前段能跑到 90% 利用率,后段只有 30%」。用算术强度(每读一字节能做多少次浮点运算)一句话就能说清。

判断瓶颈的通用判据是:把 kernel 的算术强度 II(FLOP/字节)与设备的「峰值算力 ÷ 内存带宽」比值 I∗I_{*} 相比,I<I∗I < I_{*} 时性能上限由带宽决定。下面先把 batch=1 单步 decode 的 II 算出来。

对一个稠密模型,每生成一个 token 需要约 2P2P 次浮点运算(PP 为参数量,每个参数一次乘加记两次),同时至少要把权重读一遍:

Idecode≈2PSweights+Skv, batchI_{\text{decode}} \approx \frac{2P}{S_{\text{weights}} + S_{\text{kv, batch}}}

代入 70B 稠密模型:2P=1.4×10112P = 1.4 \times 10^{11} FLOP,权重 148 GB [1],批大小为 1 时 KV 只有几百 MiB,可以忽略,于是

Idecode≈1.4×10111.48×1011 字节≈0.95 FLOP/字节I_{\text{decode}} \approx \frac{1.4 \times 10^{11}}{1.48 \times 10^{11}\ \text{字节}} \approx 0.95\ \text{FLOP/字节}

(本文自行推导,假设零缓存命中、不算注意力自身与激活的额外访存。)

不到 1 FLOP/字节意味着:每从内存读一个字节,只对应不到一次浮点运算(一次乘加按前文记两次 FLOP)。这解释了论文所测配置的 decode 为什么容易被访存卡住——GPU 在 decode 时张量核利用率最高只有 35.90%、DRAM 利用率爬到 64.09%(论文剖面数据)[1];但它不等于「任何加速器、任何 batch 都必然如此」,最终要看各设备的 I∗I_{*}。

那「把批开大」能不能救回来?能救一部分:权重只需读一遍,摊到更多 token 上。但代价是 KV 缓存随批大小线性增长:若批内 BB 个请求的上下文长度均为 TT,则 KV 容量约为 Skv⋅T⋅BS_{kv} \cdot T \cdot B(SkvS_{kv} 为每 token 跨全部层的 KV),它会先撞上容量墙 [1];同时批量 decode 的运算量也随 BB 增加,而权重的读取可以在批内复用。所以真实系统里「大 batch 把 GEMV 变成 GEMM」这条路有上限,这也是论文认为 NPU 那种「少开核、把计算压在近 DRAM 的核上」的设计思路有机会的原因。

三、为什么值得把两相拆给两种设备

先给口径导航:本文把三个能效分别叫 kernel 算力能效(TFLOPS 每 ASIC kW)、decode 相位能效(输出 token/s 每 decode 设备 ASIC kW)、全服务设备能效(输出 token/s 每 prefill 与 decode 全部设备 ASIC kW),三者不可直接混用。

论文用一张表把动机摆了出来:同一批请求(512 输入 token、128 输出 token、批大小 32,两侧各 4 张卡、TP=4、vLLM)分别跑在 A100 与 p150a 上 [1]。

指标(相位见各行)GPU(A100)NPU(p150a)比值(NPU/GPU)
Prefill 吞吐(输入 token/s)133.1652.740.40(GPU 快 2.52 倍)
Decode 吞吐(输出 token/s)15.2713.170.86(GPU 快 1.16 倍)
Decode 能效(输出 token/s 每 kW,设备 ASIC 功耗)77.11107.201.39
Decode 成本效率(输出 token/s 每千美元设备价)0.552.354.27(论文正文写 4.31)

数据来自论文 Table 1 [1]。最后一行:用表里两个两位小数反算是 2.35 / 0.55 = 4.27,论文正文写 4.31,两处口径的差异原因本文未确认,引用时以论文正文口径 4.31 为准,同时保留反算值。

这张表就是整篇论文的立论基础:prefill 差 2.52 倍,decode 只差 1.16 倍,但 decode 阶段 NPU 更省电、更便宜。 于是把前段留在 GPU、后段换到 NPU,理论上能同时拿到「前段不慢」和「后段便宜」。

为什么 decode 阶段 NPU 能追上来?论文给了两组剖面数据。GPU 在 prefill 时 QKV 投影 kernel 的张量核利用率最高 92.92%、DRAM 利用率最高 19.26%(典型的计算受限);换到 decode,同一个 kernel 的张量核利用率掉到最高 35.90%、DRAM 利用率升到 64.09%(变成访存受限),同一层里其余 kernel 的张量核利用率只有 22% 到 39%、DRAM 利用率 36% 到 72% [1]。原因不复杂:batch 为 1 时是矩阵乘向量(GEMV),并行度低、数据复用少。

NPU 的应对方式是主动少开核:decode 阶段它用的核数比 prefill 少(论文举例 FFN kernel 是 8 核对 64 核),把计算集中到离 DRAM 更近的少数核上,从而把「已分配核的利用率」做得很高——QKV 投影 79.06%、FFN 81.46%,而 GPU 同一批 kernel 只有 11.93% 和 13.44% [1]。注意这是「占已用核峰值的比例」,不是绝对吞吐:论文对「少开核」的表述是「可能限制 kernel 吞吐」(may limit),Table 4 也没有给出单 kernel 的绝对吞吐;落到能效上,NPU 的 QKV 投影 kernel 算力能效(TFLOPS/kW)反而是 167.59 对 GPU 的 226.82,输给 GPU;只有在 attention(28.34 对 22.64)与 FFN(258.99 对 255.47)上才占优或打平 [1]。

这里必须打断一下,点出这篇论文最容易读错的地方:它有三个不可直接混用的「能效」口径。

口径定义论文位置GPUNPU
kernel 算力能效该 kernel 的 TFLOPS 除以 ASIC 功耗Table 4QKV 226.82QKV 167.59
Decode 相位能效decode 输出 token/s 除以decode 设备 ASIC 功耗Table 177.11107.20
全服务设备能效输出 token/s 除以prefill + decode 全部设备的 ASIC 功耗Table 867.09(Chatbot)84.48(Chatbot)

三个数字都叫「能效」,单位与分母都不同。混用会得出完全相反的结论——按第一个口径 NPU 在 QKV 上是输的,按第二、三个口径它是赢的。本文后面凡出现「能效」,都会写明是哪个口径。

四、真正的两道坎,以及主机中转的代价

论文把障碍拆成两条,这个拆法是全文的结构骨架 [1]。

第一道坎是通信栈不通。同构 GPU 系统里,NVIDIA 的 NIXL 一类软件栈可以让网卡通过 RDMA 直接读写 GPU 显存(靠 nvidia-peermem 把显存暴露给 RDMA 子系统),所以 KV 缓存能从 A 卡显存直接进 B 卡显存。换到 NPU,各家用的是自己的通信机制与驱动栈,跟 GPU 那一套不互通。

第二道坎是张量布局不同。GPU 上张量分布在多个 DRAM 通道,但映射在一段虚拟连续地址里(论文提到固定的 256 B 粒度交织),所以「一个连续 RDMA 缓冲区」就够用。NPU 不同:它显式控制哪个张量块放进哪个 DRAM 通道(为了内存局部性、减少片外流量),于是一个张量在物理上是分散在多个通道里的一堆块。论文引用 Google TPU 的 tiled 布局来说明这种差异在业界是常态 [1](TPU 是 Google 的张量处理加速器;此处只作布局差异的例子,不是 HAWK 的验证平台)。

flowchart LR
  subgraph P["Prefill 节点(GPU)"]
    A["A100 PCIe 40GB x4<br/>TP=4"]
    B["RDMA 注册的<br/>连续 GPU 缓冲区"]
  end
  subgraph H["主机路径(HAWK 绕开)"]
    C["主机内存<br/>两次拷贝 + 主机干预"]
  end
  subgraph D["Decode 节点(NPU)"]
    E["每通道一个 RDMA 缓冲区<br/>按 NPU 张量布局分配"]
    F["NPU KV cache pool<br/>拷入后无需再排版"]
  end
  A -->|"① 布局变换(GPU 上做)"| B
  A -.->|"对照路径:主机中转;1.83x-5.25x 是同构 GPU 间的测值"| C
  C -.-> E
  B ==>|"② RDMA 直连 200 Gbps HDR IB"| E
  E ==>|"③ 批量化传输 + 拷入 KV pool"| F

这张图说明了什么:HAWK 的核心不是「更快的光纤」,而是把虚线那条主机中转路径删掉,同时让目标侧的缓冲区一落地就是 NPU 能直接吃的形状。

主机中转有多贵?论文在 GPU 到 GPU 之间量过:传输量从 10 MB 增到 1.2 GB 时,主机中转的延迟是直连的 1.83 倍到 5.25 倍 [1]。注意这是同构 GPU 之间的对比——也就是说,即使两块芯片的布局完全一样,只要中间过一趟主机,代价就已经是倍数级。异构还可能额外增加布局处理成本,具体要按实际路径去测。

顺带说一个反面教材,它能说明第二道坎有多硬。论文实现了一个对照配置:GPU 做 prefill、NPU 做 decode,直连 RDMA,但 NPU 侧用传统的一个连续缓冲区。这个配置在服务压测时直接 OOM 失败了——因为连续缓冲区不符合 NPU 的通道布局,内存使用在通道之间失衡,有的通道已经耗尽、别的通道还空着,后续张量分配不下去 [1]。论文没有把这个配置放进定量对比,因为它跑不完。一个「看起来只是少优化了一点」的实现选择,直接把系统跑挂,这是本文认为最值得记住的一条工程事实。

五、第一招:把 NPU 内存也挂上同一套 RDMA 栈

HAWK 的第一个动作是「接通道」:在 Linux 的 RDMA 栈(内核态 ib_core、用户态 libibverbs)下面,给 GPU 用现成的 peer memory client(nvidia-peermem),给 NPU 自己写一个 peer memory client [1]。

peer memory client 的接口很朴素,就是把五个回调补齐,让 RDMA 子系统在注册内存时能问「这块地址是不是你的、对应的物理页在哪、能不能映射成网卡能访问的 DMA 地址」[1]:

回调作用
npu_acquire判断 RDMA 子系统请求的地址范围是否属于 NPU 设备内存
npu_get_pages取出该地址范围对应的 NPU 内存页
npu_dma_map把这些页映射成网卡可访问的 DMA 地址
npu_dma_unmap释放 DMA 映射
npu_put_pages释放取出的内存页

做完这一步,两侧的网卡就能直接读写对端设备内存,数据路径上不再有主机。论文把这个支撑做在 Tenstorrent 的驱动里(用户态驱动 v0.68.0、内核态驱动 v2.5.0),上层搬运逻辑写在 Mooncake Transfer Engine v0.3.6 之上——它是一个负责跨设备内存传输的开源传输引擎,HAWK 改的是它上面的「缓冲区配对 + 布局变换」这一层 [1][5]。

flowchart TB
  APP["应用 / 传输引擎(Mooncake Transfer Engine)"] --> US["用户态:libibverbs"]
  US --> KS["内核态:ib_core"]
  KS --> NIC["RDMA 网卡(ConnectX-6)"]
  KS --> PC1["GPU peer memory client<br/>现成(nvidia-peermem)"]
  KS --> PC2["NPU peer memory client<br/>HAWK 新写(五个回调)"]
  PC1 --> G["GPU 显存"]
  PC2 --> N["NPU 内存(多 DRAM 通道)"]

这张图说明了什么:异构搬运的第一性问题是「网卡能不能拿到对端设备内存的 DMA 映射」,谁能回答这个问题,谁就能进入同一条 RDMA 数据通路;HAWK 的贡献是把 NPU 侧这个回答补上了。

选择 Tenstorrent 作为 NPU 平台的理由,论文写得很直接:这是我们知道的唯一一个开源软件栈、允许做 HAWK 所需底层改动的 NPU 平台 [1]。这条限制很关键——它意味着论文的「可行性」结论部分依赖于「你手上那块 NPU 的驱动能不能改」。闭源驱动的加速卡,这一招未必用得上。

六、第二招:按目标布局分配缓冲区

接通道只解决了「能不能直连」,没解决「搬过去能不能直接用」。于是第二个动作是在 NPU 侧按目标张量布局分配 RDMA 缓冲区。

论文先用两个式子把两种内存表示区分开。NPU 张量是一组「指针—长度」对,每对指向一个 DRAM 通道里的连续块:

Tnpu={(p1,s1),(p2,s2),…,(pNch,sNch)}T_{\text{npu}} = \{(p_1, s_1), (p_2, s_2), \dots, (p_{N_{ch}}, s_{N_{ch}})\}

而传统连续缓冲区是单个「基址—长度」对:

Bcontig=(base,size)B_{\text{contig}} = (base, size)

这个差别带来两个后果 [1]。其一,搬过去不能直接用:即使把张量的维度顺序和元素顺序都改对了,落在连续缓冲区里的数据仍要再做一次搬运或调整才能变成 NPU 张量对象。其二,会用出内存碎片:连续缓冲区的布局不跟随 NPU 的通道划分,通道之间的占用会失衡,某些通道被占满、另一些还空着,后续张量分配就被卡住——上面那个 OOM 的对照配置就是这么挂的。

HAWK 的做法是:每个 DRAM 通道分配一个虚拟连续的缓冲区,并按目标布局组织它们(论文为此加了六个 C++ 接口:map_buffer_dma、get_device_num_bank、get_buffer_address_bank、get_buffer_size_bank、unmap_buffer_dma 等)[1]。

代价是什么?缓冲区从 1 个变成 NchN_{ch} 个,管理开销和 RDMA 请求数都会上升。论文给的界是:缓冲区数量上限 = NPU 的 DRAM 通道数,通常十个以内,每个通道内部仍然是连续的,所以额外开销相对单缓冲方案「modest」(适度)[1]。在 p150a 上这个数是 8 [1]。

flowchart LR
  subgraph G["GPU 侧(变换后)"]
    G1["G' : [N_ch, -1, tile_chunk]<br/>每个通道的数据已聚成连续大块"]
  end
  subgraph B["NPU 侧缓冲区"]
    B1["通道 0 缓冲区"]
    B2["通道 1 缓冲区"]
    B3["..."]
    B4["通道 7 缓冲区"]
  end
  subgraph T["NPU KV pool"]
    T1["按 tensor 布局落位<br/>可直接被 decode kernel 消费"]
  end
  G1 ==>|"每段对应一个通道,单次传输块变大"| B1
  G1 ==> B2
  G1 ==> B3
  G1 ==> B4
  B1 --> T1
  B2 --> T1
  B3 --> T1
  B4 --> T1

这张图说明了什么:把「一个连续缓冲区」换成「每通道一个缓冲区」,换来的不是更快的光纤,而是传输时就把目标布局对齐做掉——数据到达时已是目标形状;接收后仍要做一次设备内拷贝进 KV pool(见第八节),但不再需要布局重排。

七、第三招:把布局变换拆成两段,让传输顺手完成对齐

第三个动作解决一个矛盾:要在传输前把布局改对,就得做数据重排;而数据重排本身要花时间与带宽。论文把它拆成两段,中间夹一次传输 [1]。

先定义两个符号:tile 是 NPU 分块布局的基本单元,tile_chunktile\_chunk 是一个 tile 内的元素数;下面形状表达式里的 −1-1 表示该维由总元素数自动推定,而不是一个固定值。

第一段在 GPU 上做,把张量重排成「每个目标通道的数据聚成一块连续区域」的形状:

shape(G′)=[ Nnpu_channel, −1, tile_chunk ]\text{shape}(G') = [\,N_{\text{npu\_channel}},\ -1,\ \text{tile\_chunk}\,]

这样做有两个好处:单个 RDMA 传输的块变大(请求数变少),而且 GPU 侧在 prefill 阶段还有内存带宽余量,重排的额外访存可以塞进这段余量里——这是论文明确解释的设计取舍 [1]。

第二段由传输本身完成。把变换后张量的每一段连续区域,映射到对应的每通道 NPU 缓冲区,用指针算术直接对齐:

ptr(G′)+c⋅stride → RDMA  Tc,∣transfer∣=sizetransfer(c)\text{ptr}(G') + c \cdot \text{stride} \ \xrightarrow{\ \text{RDMA}\ }\ T_c,\qquad |\text{transfer}| = \text{size}_{\text{transfer}}(c)

其中 cc 是通道下标,stride\text{stride} 是每一段在 G′G' 里的字节跨度,TcT_c 是该通道的 NPU 缓冲区。落到缓冲区的数据形状已经等于 NPU 张量要求的形状,于是 decode 侧在拷入 KV pool 后可以直接消费,不需要后置重排。

论文还解释了为什么不走另一条更「直接」的路:如果按目标布局逐小块映射(每个元素或每个 tile 单独一次 RDMA),单次传输会缩到几百字节,协议开销与请求处理开销吃掉全部收益 [1]。这条路看起来最「正确」,实际最慢——这是本文认为第二值得记住的工程事实:在搬运路径上,「对齐得越精细」不等于「越快」,要把传输粒度当成第一约束。

八、端到端流程:五步摘要,两处容易忽略的细节

论文用一段伪代码把流程固定下来(Algorithm 1),省略了第一个 token 的传递(那是一个整数):[1]

  1. decode 侧发起请求:sendKVRequest(prefill, requestId)。
  2. prefill 侧按 requestId 取出 KV 张量,做第一段布局变换,向自己的 RDMA 缓冲区申请空间,把张量拷进去,然后把「总长度 + 缓冲区偏移」这些元数据发给 decode 侧。
  3. decode 侧按元数据把「GPU 缓冲区的一段」与「NPU 各通道缓冲区」两两配对,生成 RDMA 请求列表,批量提交(而不是逐条串行提交)。
  4. 传输完成后,decode 侧把收到的数据从 RDMA 缓冲区拷进 NPU 的 KV cache pool。
  5. 两侧各自释放占用的缓冲区区域。

两处容易忽略的细节。第一,元数据里带的是偏移,不是地址——意味着 GPU 侧的缓冲区是可以复用的环形/池化结构,不需要每次传输重新注册内存。第二,配对发生在 decode 侧而不是 prefill 侧:接收方才知道自己每个通道的缓冲区在哪、什么形状,发送方只需要交出一段连续数据。这个职责划分把「布局知识」留在了拥有该布局的设备一侧,是整篇论文里最容易迁移到别处的设计思想。

还有一处论文没展开、但工程上绕不开的:两侧缓冲区的生命周期管理。伪代码里只有「释放」两步(D9 与 P9),但实际上 NPU 侧每个通道的缓冲区被多个并发请求共用,谁先谁后、满了怎么办,论文没有写。这一段在实践中往往是 bug 高发区,读论文时应该把它当成「未给出」而不是「不存在」。

评测配置见下(论文 Table 7)[1]:

项目配置
Prefill 硬件4 张 NVIDIA A100 PCIe 40 GB
GPU-only decode 硬件4 张 NVIDIA A100 PCIe 80 GB
NPU decode 硬件4 张 Tenstorrent p150a
节点内互连prefill 侧 NVLink Gen 3 + PCIe Gen 4;NPU 侧以太网链路
节点间网络200 Gbps HDR InfiniBand,每节点一块 ConnectX-6
服务框架vLLM v0.10.0,每相位一个实例,各自 TP=4
模型Llama 3.1 70B(论文记 148 GB 权重,即 137.8 GiB,本文自行换算)

九、结果怎么读:三个层次,一个口径缺口

论文的四组对比是:GG-Host(GPU 对 GPU、主机中转)、GN-Host(GPU 到 NPU、主机中转 + NPU 侧布局调整)、GG-Direct(GPU 对 GPU、RDMA 直连)、GN-HAWK(GPU 到 NPU、HAWK)[1]。

先把三个倍数的分子分母摆出来,再读数字:延迟比 = GN-Host ÷ GG-Host(越大表示主机中转越慢);HAWK 加速比 = GN-Host ÷ GN-HAWK;服务能效比 = GN-HAWK ÷ GG-Direct。三者不是同一指标,下面的 8.91 与 3.79 属于第一个,1.26 倍属于第三个。

第一层,单次搬运延迟(Figure 9,全部归一化到 GG-Host)。 随传输量从 10 MB 增到 1280 MB:GG-Host 是基准 100%;GN-Host 的延迟是 GG-Host 的 8.91 倍降到 3.79 倍;GG-Direct 从 GG-Host 的 66.30% 降到 14.77%;GN-HAWK 从 77.25% 降到 14.68% [1]。翻成两句人话:小传输量时 HAWK 还吃亏(10 MB 处比 GG-Direct 慢约 16.5%,因为残留的布局变换成本摊不开),大传输量时两者就分不出来了(1280 MB 处 GN-HAWK 甚至比 GG-Direct 低 0.61%,论文 §1 引言写的是「0.65% 的差异」)[1]。这两个百分数都是本文按论文 Figure 9 的归一化读数反算,不是论文直接给出的比值。

然后是那个口径缺口。论文引言写「比朴素的主机中转快最多 27.69 倍」[1],但全文没有给出这个数字对应的传输量与测法。用 Figure 9 的两条归一化读数反算:10 MB 处约 8.91 / 0.7725 ≈ 11.5 倍,1280 MB 处约 3.79 / 0.1468 ≈ 25.8 倍。25.8 倍与 27.69 倍同量级、相差约 6.8%,但 25.8 这个反算值本身已被显示精度锁死:即使把 3.79 与 14.68% 都取到最宽的舍入边界,比值也只在约 25.77 到 25.86 之间,够不到 27.69,所以这个差额不能由显示值的四舍五入解释。 仅凭正文公开的端点归一化数值,无法确定 27.69 对应的数据点或原始值;本文只记录「无法复现到该精确值」,不据此判定论文数字对错。本文的处理是:引用时写「论文称最多 27.69 倍,按 Figure 9 反算约 25.8 倍」。

第二层,在线服务(Figure 10 到 13)。 SLO 设为 TTFT/TPOT = 2000/200 ms(Chatbot)与 15000/200 ms(Summarization)[1]:

以下相对差均以 GG-Direct 为比较基线;「90% SLO」在请求率一行指 90% TTFT-SLO 达成点(Figure 10),在输出吞吐一行指 90% TTFT/TPOT 联合 SLO 达成点(Figure 13)。

指标(判据见行内)ChatbotSummarization
GG-Host 掉到 90% TTFT-SLO 以下的请求率0.40 req/s0.38 req/s
GN-HAWK 相对 GG-Direct 的请求率差(90% TTFT-SLO 处)2.90%5.90%
输出吞吐差(90% TTFT/TPOT 联合 SLO 处,GN-HAWK 对 GG-Direct)0.48%7.88%
请求率(90% TTFT/TPOT 联合 SLO 处,GG-Direct / GN-HAWK)0.65 / 0.65 req/s0.65 / 0.60 req/s

这里有两个必须区分的数字,因为它们的分母不同:2.90% 与 5.90% 是「请求率差」(TTFT 维度,Figure 10),0.48% 与 7.88% 是「输出吞吐差」(Figure 13)。摘要里的 7.88% 指的是后者,不是「请求率差 7.88%」。另外 Summarization 的 SLO 达成处 GG-Direct 是 0.65、GN-HAWK 是 0.60,论文把这个 7.69% 的差归因于 NPU 略低的 decode 性能导致 TPOT 越界,而不是搬运开销 [1]。GN-Host 则根本没进 Figure 13——它在最低请求率下都达不到 90% SLO [1]。

第三层,能效与成本(Table 8、Table 9)。

指标(90% SLO 处)负载GG-DirectGN-HAWK比值
全服务设备能效(输出 token/s 每 kW)Chatbot67.0984.481.26
全服务设备能效(输出 token/s 每 kW)Summarization41.0147.181.15
设备成本效率(输出 token/s 每千美元)Chatbot2.054.152.03
设备成本效率(输出 token/s 每千美元)Summarization1.252.351.88

这里就是版本冲突的现场。arXiv 摘要页上写的成本效率是 1.72 倍(那是 v1 摘要的口径,页面元数据在 v2 更新后仍停留在旧文本)[2];v2 的 PDF 正文与结论都写 2.03 倍,且与 Table 8 的 4.15 / 2.05 = 2.02 一致 [1]。引用时应采用 v2 的 2.03 倍,并注明摘要页显示值滞后。 本文按后者,同时把这个冲突留在核验记录里。

论文还做了一组换 GPU 的对照:把 decode 侧的 A100 换成 H100(记作 GGH-Direct)。这时 GN-HAWK 的吞吐只低 6.53%(Chatbot)与 6.50%(Summarization),能效高 1.04 倍,成本效率高 3.46 倍 [1]。这组数据比主结果更能说明问题:能效优势从 1.26 倍缩到 1.04 倍,原因是 H100 在 decode 时功耗更低;成本优势反而放大到 3.46 倍,原因是 H100 单价高(论文用的价格是 p150a 1400 美元、A100 40GB 4000 美元、A100 80GB 7000 美元、H100 16000 美元)[1]。换句话说:这套异构拆分的收益高度依赖「拿什么 GPU 对什么 NPU」,不是一个普适常数。 论文自己也把成本效率写成「参考而非定论」,因为设备价格随行情波动 [1]。

三个容易误读的地方

第一,「7.88%」是输出吞吐差,既不是延迟差也不是请求率差。同一组实验里另有两个不同的百分数:请求率差 2.90%(Chatbot)与 5.90%(Summarization)、SLO 达成处的请求率差 7.69%(Summarization)。这里既有输出吞吐差,也有请求率差;而请求率还必须区分「仅按 TTFT 取点」与「按 TTFT/TPOT 联合约束取点」两种情况,不能仅凭百分数互换,否则会得出「NPU 比 GPU 慢 7.88% 的请求率」这种错误结论。

第二,GN-Host 在 Figure 13 里缺席不是画图省略——它连最低评估请求率都达不到 90% SLO,因此没有「90% SLO 处的吞吐」可画 [1]。看到某条曲线只出现一半时,先想「它是不是根本没跑到那条线」,而不是「作者漏画了」。

第三,90% SLO 处的请求率在 Chatbot 上 GG-Direct 与 GN-HAWK 都写到 0.65 req/s。注意这里是「综合 SLO(TTFT 与 TPOT 同时达标)」口径,而 2.90% 是「单看 TTFT」口径的请求率差,两者不能互相解释:论文公开文本只报告 Figure 12 上两者都达到 0.65 req/s,并没有给出这两条曲线之间的精确差 [1]。

十、符号与术语表

符号 / 术语含义量纲 / 备注
LL模型的解码器层数Llama 3.1 70B 为 80
HkvH_{kv}KV 头数(GQA 分组后的头数)Llama 3.1 70B 为 8
dd每个注意力头的维度128
bbKV 元素字节数论文未明示;本文按 bf16 取 2
PP模型参数量本文算术强度推导用 70B
BB批大小KV 体积随它线性增长
SkvS_{kv}每 token 的 KV 占用本文推导 320 KiB
NchN_{ch}NPU 的 DRAM 通道数(= 每通道缓冲区数上限)p150a 为 8,论文称通常 ≤10
tile_chunkNPU tile 的元素数论文未给出具体值
prefill一次性处理全部输入 token 的相位计算受限(GEMM)
decode逐 token 生成的相位访存受限(GEMV)
PD 分离把 prefill 与 decode 放到不同实例/节点论文 Figure 3
peer memory client把设备内存暴露给 RDMA 子系统的驱动模块GPU 侧现成,NPU 侧 HAWK 新写
GG / GN前一位是 prefill 设备,后一位是 decode 设备GG=全 GPU,GN=GPU 到 NPU
90% SLO 达成使 90% 请求满足 TTFT/TPOT 约束的请求率单位 req/s

十一、边界与未解

按重要性排,本文认为这篇论文有六处边界需要读者自己接住。

第一,单平台。NPU 侧只有 Tenstorrent p150a,而且选它的理由是「驱动开源、能改」,这既是论文的诚实,也是它的限制:闭源驱动的加速卡未必能复现这套 peer memory client [1]。

第二,单模型、单并行度。只有 Llama 3.1 70B、只有 TP=4。论文自己写了原因:Tenstorrent 的软件栈把每个受支持的模型与特定设备类型、设备数量绑定 [1]。所以「7.88% 的差距」不是这个机制的固有常数,只是这一组配置下的读数。

第三,没有端到端质量退化数据。论文说异构配置的 ROUGE 与全 GPU 配置「几乎相同」[1],但没给具体分数,也没做更长上下文的生成质量对比。

第四,KV 数据类型未交代,由此产生第二节那个「10 MB 对应 64 token」与 bf16 推导(30.5 token)对不上的口径缺口。

第五,27.69 倍无法从公开数据复现(见第九节),只能反算到约 25.8 倍。

第六,没有和 MLA 一类的 KV 压缩方案交叉评估。Llama 3.1 70B 用的是 GQA(8 个 KV 头),如果换成 DeepSeek 系那种低秩压缩的 KV(每 token 的 KV 体积显著小于 320 KiB)[7],搬运量会小一个档次,「搬运是否是瓶颈」的结论要重算。论文没有讨论这一点,本文认为这是最值得后续补的一块。

如果只能记住一条「该怀疑什么」,本文的建议是:怀疑所有「倍数」类结论的可移植性。 论文里同一套机制对 A100 与 H100 的全服务设备能效比分别是 1.26 倍与 1.04 倍 [1]——这里要比较的是「各自相对基线的优势幅度」(多出 26% 与多出 4%),而不是说 1.26 这个总比值本身是 1.04 的几倍;那么对另一块 NPU、另一代网络、另一种 KV 宽度,这几个倍数会变成多少,论文没有、也无法给出答案。能被搬走的是机制(peer memory client + 布局感知缓冲区 + 两段式变换),不是这些数字。

十二、工程含义:什么时候值得动这件事

把上面的机制翻译成决策问题,本文给出这份清单(判断依据全部来自论文口径,不是实测):

  • 值得考虑:decode 负载占比高、GPU 在 decode 阶段利用率长期偏低(论文里 QKV kernel 张量核利用率最高 35.90%),且手上 NPU 的驱动可改、能实现 peer memory client。
  • 值得考虑:能接受「prefill 留在现有 GPU 集群、只为 decode 建一条新硬件池」,即不做整机替换。
  • 要谨慎:如果你的 KV 缓存已经被压缩过(MLA、KV 量化到 1 bit 量级),先把每请求 KV 体积按第二节的公式重算一遍;搬运量降下来之后,这套优化能省下的纯传输时间也会同比下降,但端到端收益还要按目标体积重测。
  • 要谨慎:如果 decode 侧的 GPU 不同于主实验里的 A100(论文另测了用 H100 做 decode 的配置:全服务设备能效比从 1.26 倍降到 1.04 倍)[1]。
  • 不要照抄:不要直接照搬论文里那个导致 OOM 的「单一连续 RDMA 缓冲区 + 事后重排」配置;上异构前先验证目标平台的通道布局、分配策略与容量余量 [1]。
  • 不要忽略:主机中转在同构 GPU 之间就已经是 1.83 到 5.25 倍的代价 [1];任何跨设备方案的第一优先级都是「把主机从中转路径上摘掉」。

一句话总结这篇论文的价值:它证明的不是「NPU 能替代 GPU」,而是**「异构拆分的可行性取决于你能不能把布局知识放到接收端、把对齐动作塞进传输过程」**——这是一个可以搬到别的异构场景(GPU 到 TPU、GPU 到 PIM、甚至同一机箱内的不同加速卡)的设计模式,而不只是一次硬件组合的性能报告。

12.1 如果 KV 已经压过:先把搬运量重算一遍

本文第二节那个 320 KiB/token 是按 bf16 假设计算的值。真实系统里 KV 常被压过,搬运量会同比下降,纯传输那一段的耗时也跟着下降,但端到端收益还得看固定开销占多大比例,需要按目标体积重新测。用第一节的定义式,只改元素字节数 bb:

KV 元素宽度每 token、单层(2×8×128×b2 \times 8 \times 128 \times b 字节)每 token、跨全部 80 层ShareGPT 均值请求(783 token)
bf16(2 字节)4,096 字节320 KiB244.7 MiB
FP8(1 字节)2,048 字节160 KiB122.3 MiB
4 bit(0.5 字节)1,024 字节80 KiB61.2 MiB

(全部为本文自行推导,按 2LHkvdb2LH_{kv}db 与上表常量计算。)这里正好对上第二节那个缺口:在「全模型未分片 + KV 为 1 字节 + 把 10 MB 按 10 MiB 理解」这组假设下,10 MiB 除以 160 KiB 恰好是 64 个 token,与论文括注完全一致;若按 TP=4 单卡 bf16(每 token 80 KiB)则是 128 个 token。所以「1 字节 KV」只是能精确解释 64 的一个合理猜测,论文没有披露足够信息确定实际口径,本文不把它写成唯一可能。

若换成 MLA 一类的低秩压缩 KV,每 token 的 KV 体积会显著小于 320 KiB(具体比例须按对应论文原文核对,本文不引用未核对的数字)[7]。结论要谨慎:KV 体积减少会降低纯传输那一段的时间,但端到端收益还取决于固定开销(布局变换、通道配对、落池拷贝)与服务本身的瓶颈,不能仅按字节数线性外推。

12.2 复现这份结果需要动到哪几层

论文列出的改动面总共四层,缺一层都跑不通 [1]:

  1. 驱动层:给 NPU 写一个 peer memory client(五个回调),并让 RDMA 子系统认这块内存;论文改的是 Tenstorrent 的用户态驱动 v0.68.0 与内核态驱动 v2.5.0。
  2. 缓冲区层:在 NPU 侧实现「每通道一个虚拟连续缓冲区」的分配与查询接口(六个 C++ 接口)。
  3. 传输引擎层:在 Mooncake Transfer Engine v0.3.6 上实现「变换后的 GPU 缓冲区段落 → 各通道 NPU 缓冲区」的配对与批量提交。
  4. 服务框架层:用插件把 NPU 执行栈接进 vLLM v0.10.0,并保持每相位一个实例、各自 TP=4 的形态。

对想在自己的硬件上评估这件事的团队,这份清单的价值大于那 7.88%:它把「要不要做」变成了「这四层里我有几层能改」。如果第 1 层改不动(闭源驱动),后面三层都无从谈起。

📋 来源与核验记录

本文所有外部事实均来自本轮实际打开并核对过的一手材料(核验时点 2026-10-29,北京时间)。为便于复核,每条来源单独给出 URL。

  1. HAWK 论文正文(v2 PDF,14 页 / 13 图 / 9 表) URL: https://arxiv.org/pdf/2610.29873v2 核对内容:Table 1、Table 3、Table 4、Table 5、Table 6、Table 7、Table 8、Table 9、Figure 9 至 Figure 13,以及 Algorithm 1 与 §4.1–§4.5、§5.1–§5.4。PDF 页脚标注 arXiv:2610.29873v2 [cs.AR] 23 Oct 2026。
  2. arXiv 摘要页(版本与摘要字段核对) URL: https://arxiv.org/abs/2610.29873 核对内容:提交历史 v1 为 2026-10-21 15:25:35 UTC、v2 为 2026-10-23 05:45:42 UTC(两份大小均为 1,178 KB);页面摘要字段仍写成本效率 1.72 倍,与 v2 正文的 2.03 倍冲突,本文按 v2 正文取值并在此记录冲突。
  3. Llama 3 模型家族技术报告(arXiv:2407.21783,The Llama 3 Herd of Models) URL: https://arxiv.org/abs/2407.21783 核对内容:Llama 3.1 70B 的 GQA 分组结构(64 个查询头、8 个 KV 头)。
  4. Llama 3.1 70B 公开配置(NousResearch 镜像;meta-llama 原仓库需授权) URL: https://huggingface.co/NousResearch/Meta-Llama-3.1-70B/blob/main/config.json 核对内容:本轮实际读取字段 num_hidden_layers=80、num_key_value_heads=8、num_attention_heads=64、hidden_size=8192、max_position_embeddings=131072、torch_dtype=bfloat16、vocab_size=128256;head_dim 字段未显式给出,按 8192/64 推得 128。
  5. Mooncake 论文(arXiv:2407.00079,KVCache-centric 分离式架构) URL: https://arxiv.org/abs/2407.00079 以及 HAWK 所依赖的传输引擎开源仓库(论文声明使用 Transfer Engine v0.3.6) URL: https://github.com/kvcache-ai/Mooncake
  6. SGLang 论文(arXiv:2312.07104),用于 PD 分离的系统背景 URL: https://arxiv.org/abs/2312.07104
  7. DeepSeek-V2(arXiv:2405.04434,MLA 低秩 KV 压缩),用于第 12.1 节的对照 URL: https://arxiv.org/abs/2405.04434
  8. NVIDIA A100 官方产品页,用于确认 A100 存在 PCIe 40 GB 与 80 GB 两种规格(论文 prefill / decode 两侧各用一种) URL: https://www.nvidia.com/en-us/data-center/a100/
  9. Tenstorrent 开源推理栈,用于确认论文所选 NPU 平台软件栈开源可改(这是论文选择该平台的前提) URL: https://github.com/tenstorrent/tt-inference-server

补充数字出处索引(逐个交代正文数字对应的论文位置):

  • 0.48%:论文 Figure 13 与 §5.3.4,Chatbot 负载下 GN-HAWK 相对 GG-Direct 的输出吞吐差 [1]。
  • 0.65%:论文 §1 引言的延迟差表述(1280 MB 处);按 §5.2 的 14.68% 与 14.77% 反算约 0.61%。
  • 6.8%:本文自行推导,(27.69 − 25.82) / 27.69 ≈ 6.76%,用于说明 27.69 与公开端点反算值之间的相对差。
  • 100%:Figure 9 的归一化基准(GG-Host 记作 100%),不是性能数字 [1]。
  • 11.93% 与 13.44%:论文 Table 4 里 GPU 侧 QKV 投影与 FFN 投影的「compute utilization(占已用核算力峰值的比例)」[1]。
  • 14.68% 与 14.77%:论文 Figure 9 在 1280 MB 处 GN-HAWK 与 GG-Direct 相对 GG-Host 的归一化延迟 [1]。
  • 16.5%:本文自行推导,由 Figure 9 在 10 MB 处的两条归一化读数相除得到(77.25% 对 66.30%),不是论文直接给出的数字。
  • 19.26%、35.90%、22%、36%、39%:论文 §3.1 的 GPU 剖面数据(prefill 时 QKV kernel 张量核利用率最高 92.92%、DRAM 最高 19.26%;decode 时张量核最高 35.90%、DRAM 最高 64.09%;同层其余 kernel 张量核 22% 到 39%、DRAM 36% 到 72%)[1]。
  • 2.90% 与 5.90%:论文 Figure 10 与 §5.3.1,90% TTFT-SLO 处 GN-HAWK 相对 GG-Direct 的请求率差(Chatbot / Summarization)[1]。
  • 6.50%:论文 Table 9 与 §5.4.3,Summarization 负载下 GN-HAWK 相对 GGH-Direct(H100 做 decode)的输出吞吐差 [1]。
  • 6.53%、7.69%、7.88%、79.06%、81.46%:6.53% 为 Table 9 / §5.4.3 的 Chatbot 侧吞吐差;7.69% 为 §5.3.3 中 Summarization 在 90% SLO 处的请求率差;7.88% 为 Figure 13 / §5.3.4 的 Summarization 输出吞吐差(也是论文摘要里唯一的 7.88%);79.06% 与 81.46% 为 Table 4 里 NPU 侧 QKV 投影与 FFN 投影的 compute utilization [1]。

本文自行推导的部分(与官方数字分列):

  • 每 token KV 体积 320 KiB、两种负载的 KV 体积(244.7 / 280.9 / 683.1 / 893.8 MiB)与 25 GB/s 线速下的纯传输时间(10.26 / 11.78 / 28.65 / 37.49 ms):按 Skv=2LHkvdbS_{kv} = 2LH_{kv}db 与 t=S/BWt = S/BW 计算,常量为来源 4 的配置与前文的 200 Gbps。
  • decode 算术强度约 0.95 FLOP/字节:按 2P2P 与 148 GB 权重计算,假设零缓存命中。
  • 第 12.1 节三种 KV 宽度下的每 token 体积(320 / 160 / 80 KiB 与 244.7 / 122.3 / 61.2 MiB):只改元素字节数 b。
  • 「10 MB 对应约 30.5 个 token」(bf16)与「约 61 个 token」(1 字节 KV):10 MB 除以每 token 字节数。
  • 表 1 反向比值(2.52 / 1.16 / 1.39 / 4.27)、Table 8 与 Table 9 的比值复算(1.26 / 1.15 / 2.03 / 1.88 / 1.04 / 3.46):均由论文表内两位小数反算;其中 4.15 / 2.05 反算为 2.02、论文写 2.03,2.35 / 0.55 反算为 4.27、论文写 4.31,两处末位差异原因未确认,引用一律以论文正文口径为准。
  • 25.8 倍(Figure 9 反算的上限)与 11.5 倍(10 MB 处):按「GN-Host / GG-Host = 8.91 到 3.79」与「GN-HAWK / GG-Host = 0.7725 到 0.1468」两组归一化读数相除得到,用于与论文引言的 27.69 倍对照。
  • 模型权重的 GiB 换算(148 GB = 137.8 GiB):按十进制 GB 与二进制 GiB 的定义换算。