☰
NInfer 量化 GEMM 算子调优指南:200+ 内核文件背后的单卡性能秘密
2026/10/3 17:01:41 网站建设 项目流程

NInfer 量化 GEMM 算子调优指南:200+ 内核文件背后的单卡性能秘密

【免费下载链接】ninferHigh-performance single-GPU inference for selected model checkpoints and GPUs.项目地址: https://gitcode.com/gh_mirrors/ni/ninfer

NInfer 是一个从零构建的 C++/CUDA 单卡推理引擎,专为 RTX 5090 上的 Qwen3.5/3.6 系列模型优化。它的核心性能秘密藏在 src/ops/linear/ 目录里——超过 200 个量化 GEMM 内核文件,覆盖 Q4、Q5、Q6、Q8、NVFP4、FP8 与 BF16 七种权重格式。本文将带你理解这些内核文件为何存在、如何测量与解读单卡量化 GEMM 的调优结果,无需编写一行 CUDA 代码。

上图是 examples/cli/ 中的视觉测试素材。无论是文字还是图片,最终都要经过一层层矩阵投影(Linear/GEMM)——这正是量化内核的主战场。

为什么量化 GEMM 是单卡推理的性能命脉

大模型推理中,一次 token 生成要跑几十层网络,其中矩阵乘法(GEMM)占掉绝大部分时间。单卡没有多机通信的余地,性能完全取决于:

  1. 权重读得快不快——小批量 decode 时,耗时几乎全部花在读权重上(带宽瓶颈);
  2. Tensor Core 用得满不满——大 batch/prefill 时,算力利用率决定吞吐。

量化(Quantization)把 16 位的 BF16 权重压成 4/5/6/8 位整数或 FP4/FP8,权重体积越小,显存带宽瓶颈就越容易突破。NInfer 的 持久化张量格式规范 定义了它支持的七类权重编码:

格式每权重位宽分组规模典型用途
bf1616 bit无分组高精度参考基线
fp8_e4m3fn_row_bf168 + 行缩放每行 1 个 BF16 缩放大矩阵输出头
nvfp44 bit + 块缩放每 16 权重 1 个 FP8 缩放极限吞吐(A4 激活路径)
q4_g64_fp164.25 bit64 权重共享 1 个 FP16 缩放draft head、视觉 QKV
q5_g64_fp165.25 bit64 权重共享 1 个 FP16 缩放视觉注意力输出
q6_g64_fp166.25 bit64 权重共享 1 个 FP16 缩放完整输出头
q8_g32_fp168.5 bit32 权重共享 1 个 FP16 缩放MTP 投影层

200+ 内核文件是怎么来的:一张"格式 × 策略 × shape"地图

打开 src/ops/linear/,你会看到按量化格式划分的 7 个子目录,每个目录内部又是按计算策略划分的内核族:

  • bf16/、fp8/、nvfp4/、q4/、q5/、q6/、q8/—— 每个格式一个目录
  • 目录内常见文件命名规律:*_gemv.cu(单 token 向量型内核)、*_mma.cu(Tensor Core 矩阵乘)、*_simt.cu(标量/寄存器通用路径)、*_sliced_k_mma.cu(块内切分 K 维的部分和)
  • 每个格式的shapes/子目录里,是按精确 (N,K) 形状命名的定制实现,例如 n6144_k5120.cu、n248320_k5120.cu

这就是文件数量爆炸的原因:同一个量化格式,在不同 token 数 T 下最优策略完全不同。T=1 用 GEMV 最省带宽,T=8~128 用 sliced-K 或 MMA,T≥512 用 TMA + 大规模 MMA。每种组合都要单独编译、单独调参。

视觉请求的每个 patch 也要穿过 Linear 算子(Vision suite 中登记了 patch、QKV、merger 等 7 组精确几何),所以这些形状专属内核不是"过度工程",而是真实模型几何的一一映射。

如何测量:linear bench 三类命令

NInfer 为 Linear 算子提供了独立的长期基准 bench/ops/linear_bench.cu,其合同定义在 linear-benchmark.md。新手只需记住三种用法:

单点测量:指定格式、形状和 token 数

./build/bench/ninfer_linear_bench \ --qtype q4 --policy a16 --n 4096 --k 5120 --t 8

小 T 扫描:找性能台阶

./build/bench/ninfer_linear_bench \ --qtype q4 --policy a16 --n 4096 --k 5120 \ --sweep 1:32:1

扫描会输出相邻 token 数的耗时变化百分比,用于发现不合理的阶跃和路线切换边界。

典型模型 suite:一键跑完代表几何

./build/bench/ninfer_linear_bench --suite qwen3_6_27b

27B suite 覆盖输出头(Q6)、draft head(Q4)、GDN 输出门(Q5)、MTP 投影(Q8)等 49 个精确点位,35B-A3B suite 有 37 个,--suite all合并去重为 68 个唯一点。

关键指标:带宽利用率与 Tensor Core 利用率怎么读

基准输出采用与路线无关的统一口径,方便横向比较不同量化实现:

model_bytes = 权重字节 + 2*K*T(输入) + 2*N*T(输出) 逻辑带宽 = model_bytes / 耗时 / 1e9 有效算力 = 2*N*K*T / 耗时 / 1e12

分母使用固定硬件规格:RTX 5090 标称 1792 GB/s DRAM 带宽,另附实测可持续纯读参考 1674.5 GB/s(来自 hbm_bandwidth_probe.cu)。

以官方保留报告 Q4 6144×5120 案例 为例(CUDA Graph 单次调用、冷缓存 median):

T延迟 (µs)逻辑带宽 (GB/s)带宽利用率Tensor Core 利用率
115.651069.459.68%—(GEMV 路径)
823.74711.439.70%10.12%
12881.18241.413.47%47.35%
512212.19133.17.43%72.46%
1024381.70104.25.82%80.57%

读表口诀:T=1 看带宽,T=512/1024 看 Tensor Core。小 T 阶段权重只读一遍,逼近读带宽上限就是满分;大 T 阶段权重被复用,Tensor Core 效率才是胜负手。

新手调优清单:5 步建立正确的工作流

按 linear-tuning.md 的规范,建议按此顺序推进:

  1. 先跑 suite 建立基线——--suite qwen3_6_27b记下每个 point 的 median,这是判断回退的参照;
  2. 测满热区间 1~128 的每个合法整数 T——重点核对 T=1、4、8(并发 decode 与投机验证的直接对应点);
  3. 用 sweep 定位台阶——曲线上的跳变通常对应路线切换(GEMV→sliced-K→MMA),判断它是否"合理";
  4. 大 T 锚点单独报告——T=512 与 T=1024 分别测量,不要用平均值掩盖某一侧的回退;
  5. 候选实验临时做,决定只写进生产 selector——临时 sweep 和私有 launcher 用完即删,长期基准永远只走公开linear()入口(见 op-development.md 的候选工作流)。

延伸阅读

  • 基准合同与预置 suite:docs/maintainer/linear-benchmark.md
  • 调优区间与报告规范:docs/maintainer/linear-tuning.md
  • Q4 完整调优报告范例(含 130 个实测点):docs/maintainer/examples/q4-linear.md
  • 持久化张量九种数值格式定义:docs/maintainer/tensor-formats.md
  • Linear 公开算子契约(含支持的 shape 注册表):include/ninfer/ops/linear.h
  • 各算子内核基准与构建说明:bench/README.md

理解了"格式 × 策略 × 精确形状"这个三维组织方式,你就能读懂 NInfer 200+ 内核文件背后的单卡性能秘密:不是写得更多,而是每个真实模型几何都被单独善待过。

【免费下载链接】ninferHigh-performance single-GPU inference for selected model checkpoints and GPUs.项目地址: https://gitcode.com/gh_mirrors/ni/ninfer

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询