AI图鉴

AI图鉴首页 › AI 资讯 › Kestrel_VLLM - 26 · 发射空档三步曲:事件计时 → nsys

Kestrel_VLLM - 26 · 发射空档三步曲:事件计时 → nsys → 判别实验

来源:掘金 · 发布时间:11-01 · 由 AI图鉴每小时自动聚合

26 · 发射空档三步曲:事件计时 → nsys → 判别实验 一句话:上一轮把 raw-q4 GEMV 的访存粒度改成「每 lane 一个 uint32」后,端到端从 27.2 打到 18.9 ms

26 · 发射空档三步曲:事件计时 → nsys → 判别实验

一句话:上一轮把 raw-q4 GEMV 的访存粒度改成「每 lane 一个 uint32」后,端到端从 27.2 打到 18.9 ms/token(量级 1.44×),却留下一个问题——「为什么是 1.44× 而不是 1.64×」;本篇用三种递进的手段(逐相 CUDA 事件计时 → Nsight 逐核 profile → 不碰引擎的判别实验)去量「kernel 之间 GPU 无事可做的间隙」,结论被推翻并订正了两次。

前置:建议先读 第 25 篇(访存粒度与 1.44×)。

环境:x86-64 + NVIDIA RTX 5090;模型 Qwen3.5-27B q4;工具 nsys / ncu;出厂档 build-x64\vllm_cuda.dll。

三个数:nsys cuda_gpu_trace 逐核起止量出发射空档 2.40 ms/token = 12.3%(第 4.3 节);ncu 显示 k_gdn_delta 只用 DRAM 3.04% / SM 1.19% / 0.02 waves/SM ⇒ 并行度饥饿、降字节数没用(第 4.5 节);判别实验给出每次发射的空档 = 主机侧 CPU ≈5 µs 与 设备地板 ≈1.1 µs 取大者,模型实测平均 2.05 µs(第 5.2 节)。

怎么读:结论看[一、问题与结论]与[六、串起来的教训](必读);机制看[四、第二步 · Nsight 逐核 profile]的 4.3–4.5(空档量化 + ncu 硬证据,想深挖再看);[三、第一步 · 逐相 CUDA 事件计时]与各节末尾的「审计结论与订正」是过程与原始数据(可跳,逐轮原始读数见文末附录)。

第 25 篇留下一个必须回答的问题:为什么是 1.44× 而不是 1.64×? 差额被归给了三条推断 (其中一条直指「逐层发射的空隙」)。

本篇是那条推断的清算:用三种递进的手段去量「kernel 之间 GPU 无事可做的间隙」—— 先逐相 CUDA 事件计时,再 Nsight 逐核 profile,最后写一个不碰引擎的判别实验。 结论被推翻并订正了两次:第一次「空隙只占 0.2%」,第二次「发射空档 12.3%」, 第三次才回答「这个空档到底是什么」。

它是本系列方法论的集中体现:每一步都要问「这个测量在量什么」。

状态:✅ 已落地(并两次订正)。

一、问题与结论

- 三版测量的口径不同,结论也不同,且后一版推翻了前一版:

- 第一版(逐相 CUDA 事件计时):空隙只占 0.2%(0.037 ms/token)——错在口径太窄。

- 第二版(nsys 逐核 profile):发射空档 2.40 ms/token = 12.3%——第一版的结论被推翻。

- 第三版(判别实验):「每次发射 ~2 µs 固定成本」不成立——空档与 grid / block / smem / 参数个数无关,但与内核时长强相关。

- 第一版为什么看不见空档:它量的是「相邻两个 event 标记之间的区间」,

而空档被摊进了两侧的相时间里——gap = 层循环 − Σ4 相 只覆盖 63 个层间边界,

0.037 ms 是这条窄口径的上界,不是全 token 的空档总量。

- 空档的两个机制,取大的那个:主机侧 CPU 发射成本 ≈5 µs/次(短核时是瓶颈); 设备侧 kernel 间地板 ≈1.1 µs/次(长核时主机早已领先)。模型实测的平均 2.05 µs 是两者混合。

- 最硬的一条:ncu 显示 k_gdn_delta 只用 DRAM 3.04% / SM 1.19% / 0.02 waves/SM

⇒ GDN 非投影是延迟 / 并行度瓶颈,不是带宽瓶颈。降字节数没用。

- graph 不是万能的:它能把「主机侧 5 µs」那一半消掉,但消不掉设备地板那一半。 每节点成本还随 grid 上升(grid=1 → 525 ns,grid=4096 → 2454 ns)。

- 可拿回的时间只是「乐观(上限)外插」:CUDA Graph ≈1.8 ms(9.3%)、 融小核 0.39–0.86 ms。未在模型路径实测,禁止当收益引用。

二、背景:为什么要专门量「发射空档」

第 25 篇那 1.44× 的账,卡在一句「推断」上。上一轮给出的三条解释里,有一条是:

逐层发射的空隙:每层约 10 次发射,64 层的发射间隙不随内核变快而缩小。

这条推断的麻烦在于——它看不见。它没有对应的探针:

- 反算带宽(761 GB/s)是把 16 GB 权重除以总时间得到的black-box 均值, 管你时间花在算上还是等待上,它都算进去;

- 相级 --skip 分解只能给「哪一类算子花得多」,而「发射间隙」不是一个算子;

- 微基准(--sweep)跑的是背靠背的内核,根本没有 GPU 空闲的窗口。

换句话说,「发射空档」是关键路径上的一段负空间:它既不属于任何一个核, 也不属于任何一次往返。要量它,必须换一套能看见时间线的仪器。

本篇就是这条线的三步走——而且三步的结论互相打架:

- 设备侧 cudaEvent 分段计时(逐相)→ 空隙 0.2%;

- Nsight Systems 逐核 profile(逐核起止)→ 空档 12.3%;

- 独立判别实验(stream − graph)→ 空档与什么有关。

三、第一步 · 逐相 CUDA 事件计时

上一轮的三条解释都是推断,且「跨轮基线不可自证」这一点也已被暴露。

第一步用设备侧 cudaEvent 分段计时把 18.9 ms/token 逐相拆开,把推断换成实测。

3.1 探针本身:可复现的构建线

- 新开关:-DVC_DIAG_MDL_EVENTS(编译期)+ VLLM_CUDA_MDL_EVENTS=1(运行期),

与 VC_DIAG_MDL_SKIP 同一套门控理由:出厂 DLL 里这条路径打不开。

- 插桩位置(vcuda_dev_model_step):每层 5 个标记 ⇒ 4 个区间

(in_norm / 子层+残差 / post_norm / MLP+残差),外加 3 个全局标记

(步开始 / 层循环结束 / final norm+lm_head 结束)。标记只入队,本步末尾一次同步读全部。

这套探针就落在 vcuda_dev_model_step 里,用 6 个累加槽把「4 个相 + 尾段 + 层循环」分开,gap 就是「层循环 − 四相和」:

/* 文件名:src/npu/cuda/vllm_cuda_kernels.cu —— 逐相事件计时的收尾(节选)

* 只在 -DVC_DIAG_MDL_EVENTS 构建里存在;每层 5 个标记 ⇒ 4 个区间 + 3 个全局标记。 */

#if defined(VC_DIAG_MDL_EVENTS)

double ph[4] = {0, 0, 0, 0};

for (int L = 0; L < nl; L++) {

const int base = L * 5;

for (int k = 0; k < 4; k++) { /* in_norm / 子层 / post_norm / MLP */

float d = 0.0f;

if (cudaEventElapsedTime(&d, ev[base + k], ev[base + k + 1]) == cudaSuccess)

ph[k] += (double)d;

}

}

double loop_ms = 0.0, tail_ms = 0.0;

cudaEventElapsedTime(&d, ev[nl*5 + 0], ev[nl*5 + 1]); loop_ms = (double)d; /* 层循环 */

cudaEventElapsedTime(&d, ev[nl*5 + 1], ev[nl*5 + 2]); tail_ms = (double)d; /* final+lmhead */

const double sum = ph[0] + ph[1] + ph[2] + ph[3];

s->mdl_ev_gap_ms += (loop_ms - sum); /* ★ gap = 层循环 − 四相和(只覆盖 63 个层间边界)*/

fprintf(stderr,

"[CUDA] mdl-ev AVG n=%.0f | step=%.3f ms | layer-loop=%.3f "

"(in_norm=%.3f sub=%.3f post_norm=%.3f mlp=%.3f | 4ph-sum=%.3f gap=%.3f %.1f%%) | "

"tail(fnorm+lmhead)=%.3f\n", ...);

#endif

- 口径声明:探针不改输出(同 diag DLL、--ref _q4ref64 在探针开/关下三项 maxrel

在打印精度内同值:2.2536e-06 / 2.0334e-06 / 3.3887e-06,argmax 5/5;

⚠ 这是 5 位有效数字的比对,不是逐位比对),但会扰动计时(每步 64×5+3=323 次 record)。

同构建 A/B 实测:探针开 19.611 ms/token vs 探针关 18.903 ms/token ⇒ 探针本身 0.708 ms(3.7%)。

⇒ 所有绝对值只在「探针开」这一组内部互相比较;与上一轮的 18.9 对比时要记住这 3.7%。

构建(新增 -CudaDefines,诊断档放另一个产物目录,绝不覆盖出厂档):

powershell -File tools\build\build_x64.ps1 -Cuda -OutDir build-x64 # 出厂

powershell -File tools\build\build_x64.ps1 -Cuda -OutDir build-x64-diag `

-CudaDefines VC_DIAG_MDL_EVENTS=1 # 诊断

顺带解决了上一轮记的那个构建坑:-OutDir 传相对路径时,

MinGW ld 收到的 -o 也是相对路径 ⇒ 不再触发「中文路径 → cannot open output file」,

exe 也能正常链接(本轮 rc=0)。旧写法(省略 -OutDir)会把绝对路径喂给 ld,必然失败。

★ 审计订正(6b/6a):

- 相对 -OutDir 原先在 Test-Path/New-Item 时按 cwd 解析,

而编译器在 Push-Location $root 之后按 **\(root** 解析 ⇒ 从别的 cwd 调用时会「目录建错地方」; 已把 `Push-Location\)root` 提到 OutDir 解析之前,三处基址统一。

- -CudaDefines 非空却把 -OutDir 指向出厂目录时,脚本直接拒绝(原先只有注释提醒)

—— 否则会产出「名为出厂、实为诊断」的同名 DLL。

3.2 实测(全 64 层,iters=30,n=32 平均;同会话内四组背靠背)

⚠ 口径分层(审计 5a 订正):下表前三行是 cudaEvent 口径(step 是事件窗口内),

不包含任何 host wall 时间;「探针关」那行是工具 clock() 口径(含 H2D/D2H+同步),

两者不是同一个钟,必须分开读。

探针开的 wall 口径(工具 clock(),同一构建、同一 harness):

19.611 ms/token;探针关:18.903 ms/token ⇒ 探针自身 0.708 ms。

占分母 19.611 的 3.6%、占 18.903 的 3.75%(文稿取 ≈3.7%,两个分母都写明)。

⚠ step(event)=19.482 与 wall=19.611 不是同一个量(差 0.13 ms ≈ h 的 H2D + 输出 D2H

- 主机侧开销),不可互相代入。

三跑稳定性(gap 是三个数里最稳的一个):混合档第三次独立运行

step=19.510 / sub=9.459 / post_norm=0.534 / mlp=8.644 / gap=0.037 / tail=0.470

(wall 19.642)⇒ gap 三次都是 0.037–0.039,而 sub 在 9.459–9.566、

post_norm 在 0.403–0.534 之间漂 ⇒ 「空隙≈0」这条结论不依赖抖动,

而占比类的数字要按 ±5% 读。

子层的可加性自检:把 --synthetic 得到的两类各层子层耗时按 48/16 加权

(0.16367×48 + 0.11788×16 = 9.74)对实测混合 9.566 ⇒ 1.8%(上一轮同法为 0.4%)。

⇒ 「按层型可加」在本轮成立(与上一轮被否掉的整体线性可加不是一回事)。

3.3 归因表:18.9 ms/token 花在哪

⚠ 本表是「探针开」口径,且未扣除 3.7% 探针开销(审计 4d 订正)。

★ 审计订正(4c):上一版写的「合计 = 实测 step(差 0.02%)⇒ 归因被实测验证」是错的, 那是定义闭合,不是独立校验。把两行「非投影」的定义代进求和即可看出:

合计 = P总 + (M子层 − P子层) + M_norm + (M_MLP − P_MLP) + M_gap

= P_lm + (M子层 + M_norm + M_MLP + M_gap) = P_lm + M_loop

投影项在求和里被完全抵消,合计恒等于「实测四相和 + 实测空隙 + 预测的 lm_head」。

它与实测 step 的差只等于 P_lm − M_tail。⇒ 0.02% 只说明「预测的 lm_head 0.454 ≈

实测 tail 0.453」这一件事(0.2% 吻合),不是「整张表被独立验证」。

本表唯一的独立对账就是这一条;除此之外「投影 = 字节×速率」始终是外插。

探针开销的量级影响(4d):GDN 非投影 4.84 恰恰是「探针开的子层实测 − 无探针的微基准预测」

的残差 ⇒ 探针开销会整块计入它。若 0.708 ms 按四相大小比例摊,子层约吃 0.18 ms

⇒ GDN 非投影 ∈ [4.66, 4.84](全摊给子层则是 [4.13, 4.84])。

排名结论不受影响(GDN 非投影仍是第一),但引用数字时要带上这个区间。

⚠ 另外 0.708 ms 落在哪一相并未定位(空隙只有 0.037,却总增 0.708)——

它可能在相内的 device 侧 event 成本,也可能是 host 侧 323 次 record + 每步 256 次

cudaEventElapsedTime 的开销。这一层矛盾本轮没有解释。

(tail 0.453 ms ≈ lm_head 单个投影的预测 0.454 ms ⇒ lm_head 已计入「投影」行,

final norm 本身在噪声里。)

3.4 裁决:上一轮的三条推断

- 推断 #2「逐层发射的空隙」被否定:空隙只有 0.037 ms/token = 0.2%。 ★★ 2026-10-01 二次订正:本条的口径太窄,结论在第二版被推翻。 0.037 ms 只覆盖 63 个层间边界;相内、相与相之间的空档被算进了各相时间里。 nsys 实测:每次发射后有 ~2 µs 空档,合计 2.40 ms/token = 12.3%。 ⇒ 「GPU 从头到尾没有等人」是错的;下面那句「融合不是为了省发射」也要改回来。 ⚠ 审计 4a:这 0.037 是层间边界(步起点→第 0 层、63 个层间、末层→循环尾)的测量,

相位内部(子层里 6–8 个核、MLP 里 5 个核之间)的间隙不在这个数里,

它们被算进了各自的相。所以精确表述是:

「在 63 个层间边界上未观测到可测量的空隙(≤0.6 µs/边界,已到 cudaEventElapsedTime 约 0.5 µs 的分辨极限)⇒ 0.037 是上界」,再结合「每 token 约 640 次发射 vs 单 token

19 ms」⇒ 与「主机持续领先、GPU 无空转」一致(是外推,不是直接观测)。

⇒ 「合并小投影以省发射开销」不是为了省发射;

它的收益只能来自内核自身的冷启动/短核效率。attn k/v 的 233 GB/s 因此

不是发射间隙问题(这条也排除了一个替代解释)。

- 推断 #1:由「实测 + 微基准预测」联合定位(审计 4b:上一版写「被证实并量化」过强): 非投影部分 7.01 ms/token = 36%(= 实测 step 19.482 − 预测投影 12.47),不随访存粒度变快。 最大一块是 GDN 的非投影,∈[4.66, 4.84] ms(24–25%):conv + β/a + qk-norm + 递推, 48 层 × ≈0.10–0.101 ms/层。 量级与上一轮用另一套数据反算的 0.096 ms/层一致(+5%) —— 但两者都是 「实测 − 预测」,不是完全独立。

- 推断 #3(attn k/v)保留:它占 0.2 ms 量级,且已被上面第 1 条限定为「核内效率」。

因此 1.44× 与「投影 1.63×」并不矛盾:只有 64% 的时间是会变快的那部分。 按本轮分解算结构性上限:

投影@v4 ≈ 12.47 × 1.6335 = 20.38 ms 其余 = 7.01 ms(不随本改动变快)

上限 = (20.38 + 7.01) / (12.47 + 7.01) = 27.39 / 19.48 = 1.406×

★ 这条上限反过来给上一轮的跨会话数字提供了一个(弱)独立支撑:

27.39 = 实测后总量 + 微基准预测的投影节省量(12.47×0.6335),把它与

归档的改动前 27.2 比,差 0.7% —— 一端是本会话实测、另一端是

上一会话归档,中间靠微基准模型连接 ⇒ 不是纯循环。

⇒ 「基线无法自证」的顾虑被削弱(未消除:会话标识不可回溯、

归档端自身有 27.145/27.214/27.572 的抖动、且这条链仍依赖 1.6335 这个外插值)。

★ 本节不改写上一轮记的 1.20× 与 1.44×: 本轮 wall 口径 18.888/18.903 与上一轮的 18.916/18.935 在 ±0.8% 内 ⇒ 1.44× 不动; 1.20× 本轮未复测,保持原样(仍是单次运行、无方差)。

3.5 对路线图的影响(按可拿回的时间排序)

★ 但这三项都还带一个未辨识项(审计 7,必须前置成落地门禁):

0.10 ms/层 里究竟是延迟还是吞吐,本轮没有区分。48 个 GDN 层在时间轴上是强串行

(S_t 依赖 S_{t-1}),若这 4.8 ms 主要是小核延迟 / 依赖链而不是带宽,

优化手段会完全不同(减核/融合 vs 提带宽),照「带宽」去改会白干。

⇒ 在动 GDN 非投影之前,先用逐核(nsys 或减记录版探针)把 4.8 ms 再拆一层,

并先做一次不带探针的确认(因为 4.84 同时继承了探针开销与微基准模型误差)。

3.6 审计结论与订正(第一步)

审计只做静态核对(本轮未复跑;它明确声明了这一点),但抓到了一处方法学硬伤。

审计的总结论:改动(探针)达标;结论方向达标,但「被独立验证过」这个更强的主张必须订正—— 「为什么是 1.44× 而非 1.64×」这个核心答案站得住,需要修的只是它的证据成色。

四、第二步 · Nsight 逐核 profile

第 3.5 节定了前置门禁:动 GDN 非投影之前,先用逐核手段判断那 4.8 ms 是延迟还是吞吐。

第二步用 nsys(逐核时间 + GPU 时间线)+ ncu(SpeedOfLight / Occupancy)把它做实——

顺带把第一步的结论推翻了。

4.1 方法与环境坑(可复现)

# ★ nsys 的 protobuf 拒绝非 UTF-8 的 working_directory ⇒ 仓库根含中文时**直接失败**

# (libprotobuf ERROR ... working_directory contains invalid UTF-8 data)。

# 解法:subst 一条全 ASCII 路径,所有参数都走它。

subst X: <repo_root>

nsys profile --stats=true --force-overwrite=true -o X:\nsys_gdn64 `

X:\GitHupSRC\tools\build\out\q35_gpu_model.exe X:\Modl\Qwen3.5-27B-q8local `

--vqf X:\Modl\Qwen3.5-27B-q8local\model_q4.vqf --layers 64 `

--lib X:\GitHupSRC\build-x64\vllm_cuda.dll --iters 1

nsys stats --report cuda_gpu_kern_sum --format table X:\nsys_gdn64.nsys-rep # 逐核汇总

nsys stats --report cuda_gpu_trace --format csv X:\nsys_gdn64.nsys-rep # 逐核起止(算空隙)

ncu --kernel-name regex:k_gdn_delta --launch-count 1 --section SpeedOfLight --section Occupancy <exe> ...

- ⚠ -o X:\... 的产物落在「仓库根」(X: 映射的就是仓库根):实测 .nsys-rep ≈ 20 MB、 .sqlite ≈ 320 MB。跑完必须删(本轮已删),否则仓库里躺 340 MB。

更省事的写法是把 -o 指到 %TEMP%。

- ⚠ 步数账目(审计 8 订正):上表命令行没有 --ref ⇒ 实际是 3 个 token 步

(T=1 首算 + 预热 + 1 计时),401×3 = 1203 次 rq gemv ✓ 与下表对得上。

审计复跑时带了 --ref _q4ref64 ⇒ 7 步 / 2807 次 rq,折算后逐项与本节表吻合 ≤1%。

- 被剖析的运行:--layers 64 --iters 1,出厂档 build-x64\vllm_cuda.dll(无探针,两轮都没开 VLLM_CUDA_MDL_EVENTS)。

- ⚠ 这套工具是诊断用,不进任何构建线;它不改引擎一个字节。

4.2 逐核时间表(nsys cuda_gpu_kern_sum,3 步聚合后除以 3)

一条真正的独立对账(这是第 3.3 节缺的那一条):nsys 实测 q4 投影 12.256 ms/token

vs 微基准 cold 速率外插的 12.47 ⇒ 差 1.7%。

⇒ 「投影 = 字节 × cold 速率」这个模型独立于「定义闭合」被外插对账了

(⚠ 措辞比上一版收窄:预测端仍含合成权重的不确定性)。

k_f32_gemv 的 96 次/token 也精确对上「β/a 各一次 × 48 个 GDN 层」。

这两核的「形状」就是本节要看清的对象——k_gdn_delta 一个 block 一个 v-head、每线程 128 步串行扫描:

/* 文件名:src/npu/cuda/gdn_delta_twin.inc —— 递推内核(ncu 显示 DRAM 3.04% / SM 1.19%)

* grid = 48 block(一个 v-head 一个)、block = 128 thread(thread = dv 独占 S 一列);

* 下面两条循环各 128 步,是**时间轴上的串行链**。 */

__global__ void k_gdn_delta(float *__restrict S, const float *__restrict q,

const float *__restrict k, const float *__restrict v,

const float *__restrict g, const float *__restrict beta,

float *__restrict o, int kh, int kd, int vh, int vd) {

const int vi = blockIdx.x;

const int dv = threadIdx.x;

...

float kv = 0.0f;

for (int dk = 0; dk < kd; dk++) { /* ① α 缩放 + (S·k):128 步串行,每步读+写全局 S */

float *sp = Sm + (size_t)dk * (size_t)vd + dv;

const float t = (*sp) * alpha; *sp = t; kv += t * sk[dk];

}

...

for (int dk = 0; dk < kd; dk++) { /* ② 秩一加 + (S·q):再 128 步 */

float *sp = Sm + (size_t)dk * (size_t)vd + dv;

const float t = *sp + sk[dk] * tmp; *sp = t; oa += t * sq[dk];

}

o[(size_t)vi * (size_t)vd + dv] = oa;

}

β/a 的投影则是另一种极端——只有 6 个 block:

/* 文件名:src/npu/cuda/f32_gemv_twin.inc —— β/a 的 GEMV(rows=48、cols=5120)

* 一个 warp 一行,lane 以 32 为步长扫列;grid 只有 6 个 block(wpb=8)。 */

__global__ void k_f32_gemv(const float *__restrict W, const float *__restrict x,

float *__restrict y, int rows, int cols) {

const int warp = (int)((blockIdx.x * blockDim.x + threadIdx.x) >> 5);

const int lane = (int)(threadIdx.x & 31u);

if (warp >= rows) return;

const float *wr = W + (size_t)warp * (size_t)cols;

float acc = 0.0f;

for (int c = lane; c < cols; c += 32) acc += wr[c] * x[c];

for (int off = 16; off; off >>= 1)

acc += __shfl_down_sync(0xffffffffu, acc, off);

if (lane == 0) y[warp] = acc;

}

4.3 ★ 发射空档:每 token 2.40 ms(12.3%)

Direct 量(同一次运行内,cuda_gpu_trace 的逐核起止)。审计独立复跑复现(同会话、同一 boot):

逐轮原始读数见文末 附录 · 表 A1。

★ 「这 2.4 ms 不是 CUPTI 造出来的」有两条独立论证(第一条是审计建议补的、更硬):

- wall − Σ(内核时长) 与追踪工具无关:审计复跑在无 nsys 下测得 wall 18.942 ms/token

(同一会话、同一 exe/DLL),而 nsys 下的 busy 只有 16.4–17.0 ms ⇒ 差 ~2.2 ms。

若这 2.2 ms 是 CUPTI 加的,那么无 nsys 时内核必须比 nsys 下快 13% —— 不成立

(CUPTI 的时长是 GPU 硬件时间戳,追踪开销加在主机发射路径上,不会拉长内核)。

- 跨度 18.96/19.43 与无探针 wall 18.888/18.903 同值;若每次发射被凭空加 2 µs, 跨度应膨胀到 ~21 ms。

⚠ 残留不确定性:两条都建立在「CUPTI 不改变内核时长」之上;彻底闭合需要非 nsys 的 busy 测量 (例如给第一步的探针做「减记录版」)。⇒ 证据强度高、非绝对。

- 空档个数 1168/token,均值 2.03–2.05 µs、中位数 2.02 µs(分布很窄)。

- ⚠ 窗口口径披露:上面的「跨度」定义为「该步第一次 rq gemv(第 0 层的

本文由 AI图鉴自动抓取并翻译,版权归原作者所有;如需查看原文请点下方链接。

相关 AI 工具

相关免费羊毛

同源资讯

阅读原文(juejin.cn)

标题、摘要与正文均来自该信源的公开页面,版权归原作者所有;本站自动聚合与翻译,仅作出处跳转。

← 返回 AI 资讯列表AI工具图鉴首页

返回 AI图鉴首页 · 提交工具 · 商务合作 · 关于本站 · 604 款 AI 工具分类导航 · 每日 AI 热门项目与动态