ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Mojo 内核自动调优结果分析:kprofile 与 tuning_codegen 实战指南

Mojo 内核自动调优结果分析:kprofile 与 tuning_codegen 实战指南 Mojo 内核自动调优结果分析kprofile 与 tuning_codegen 实战指南【免费下载链接】mojoThe Modular Platform (includes MAX Mojo)项目地址: https://gitcode.com/GitHub_Trending/mo/mojokprofile与tuning_codegen是 Mojo/MAX 仓库中max/kernels/benchmarks/autotune目录下的两个配套工具前者用于回顾、筛选并从kbench基准测试生成的pkl结果文件中提取洞察后者负责把筛选出的配置以 YAML 清单manifest为输入确定性生成检入checked-in到 Mojo 源码中的调优表区域。读完本文你将掌握如何用一条命令解析调优结果、如何挑选最优配置以及如何把选中的配置稳定地渲染进tuning_configs.mojo并跑通新鲜度测试从而形成基准测试 → 结果分析 → 配置落库的完整闭环。本文以 README_kprofile.md 为主体结合同目录下的 kprofile.py、tuning_codegen.py、BUILD.bazel 以及真实的 SM100 调优清单与测试用例展开讲解。一、kprofile 是什么kprofile是一个 Python 实现的命令行工具作用是剖析kbench输出的 pickle 文件。kbench会在一个参数网格grid上构建并执行 Mojo 内核基准测试把每次运行的 spec、指标与元数据如 git revision、datetime打包进pkl文件kprofile则负责把这些二进制结果变成可读、可筛选、可下钻的视图并进一步输出可供后续代码生成使用的 YAML 调优清单。你可以给kprofile同时传入多个pkl文件它会依次展示每个文件的输出并按 shape形状即一组固定的维度参数组合对结果分组同时允许你选择不同的调优参数视角。从源码结构看其核心数据流位于 kprofile.py 中的KbenchPKL类加载 pickle 后取出merged_df并丢弃name、iters两列根据指定的metric默认met (ms)做前缀模糊匹配找到合法的指标列按指标的好坏方向排序ascending_sort字典定义met (ms)越低越好其余如吞吐量、带宽类指标越高越好生成tune_df计算每条记录相对最优记录的ratio当前值 / 最优值作为后续简化表格展示的基础。可用的命令行选项kprofile基于click实现完整参数定义见 kprofile.py 中的 CLI 装饰器。常用选项汇总如下选项短选项默认值说明--output-ooutput.mojo输出文件路径生成 YAML 时用于写盘--top-t0.0从结果前 top% 中为每个参数统计出现最频繁的值形成新 spec--ratio-rfalseflag打印每个条目相对最优条目的运行时间比值表--head无-1按运行时间排序后打印前 N 条--tail无-1按运行时间排序后打印后 N 条--diff-dfalseflag对比多个 pkl 的最优运行时间第一个作为基线--metric-mmet (ms)指定剖析指标如吞吐量、带宽、GFLOPS 等--pivots-p[]指定 pivot分组维度来选择值支持[M] [N]或[M,N]写法--sort-pivots无[]指定用于排序的 pivot--merge无falseflag将多个 YAML 按 pivot 合并此时输入必须都是.yaml--query无None对合并结果执行查询如M64 and K1024--correlation-cfalseflag对多个 pkl 做 Kendall 相关性分析并输出热力图--verbose-vfalseflag打印所有未排序的条目其中--pivots使用了自定义的ComplexParamList选项类型见 kprofile.py因此--pivot[M] --pivot[N] --pivot[K]与--pivot[M,N,K]完全等价。--top的实现逻辑是阈值 (top_percentage min/max) * max选取低于该阈值的记录见top_idx函数kprofile.py随后用value_counts().idxmax()为每个参数取出现次数最多的值合成一个常见参数 spec。二、回顾与筛选 kbench 结果原文档给出了五种最常用的结果查看姿势以下逐一展开说明其输出含义与适用场景。1. 直接打印最优结果kprofile output.pkl默认行为加载output.pkl按指标排序后打印条目总数、最优条目的mesh_idx、最差与最优的指标值、最差/最优比值以及该最优 spec 对应的 shape由非 pivot 列组成形如M256/N20480/K5376最后给出最佳 spec 的完整参数。若 pkl 无效会打印Invalid pkl [...]并跳过见profile_resultskprofile.py。2. 提取 top 5% 的共性参数kprofile output.pkl --top 0.05--top 0.05表示取最优的 5% 结果统计每个参数在这些结果中出现频率最高的取值合成一个共性 spec。这在自动调优中非常实用当大量近似最优的配置共享某些参数值时说明这些值对性能的稳健性更好可以作为后续人工筛选或默认配置的依据。加-v还可以打印出这 5% 子集的完整明细。3. 简化比值表kprofile sample.pkl -r-r/--ratio会打印一张简化表格展示每条记录相对最优记录的运行时间比值当前值 ÷ 最优值比值列以绿色加粗高亮见df_to_console_table的col_stylekprofile.py。比值越接近 1 说明与最优配置越接近是快速评估参数敏感性的直观方式。4. 打印最好与最差两端kprofile sample.pkl --head 10 --tail 10--head 10打印按指标排序后的前 10 条最好--tail 10打印后 10 条最差。两段各输出一张独立表格方便对比好配置与差配置之间的参数差异找出导致性能滑坡的关键参数。5. 多文件分组对比kprofile file*.pk --head 2当一次传入多个 pkl例如file1.pk、file2.pk……时kprofile会依次展示每个文件的结果并按 shape 分组--head 2让每个文件只显示最优的两条。这在比较同一内核在不同分支、不同日期或不同硬件上的调优产出时非常有用。若想量化比较多个 pkl 的最优值可以使用--diffkprofile base.pkl new.pkl --diff --head 5--diff以第一个文件为基线逐 shape 输出当前文件最优值相对基线的比值并将结果写入shape 对应的 shape.csv见diff_baselinekprofile.py。进阶YAML 合并、查询与相关性分析除 pkl 外kprofile也接受 YAML 输入--merge模式要求输入全部为.yaml按 pivot 做 outer join 合并后可用--query过滤如--query M64 and K1024随后把满足条件的 spec 直接输出为新的 YAML走codegen_yaml流程。--correlation则对多个 pkl 合并后的数值列计算 Kendall 相关性输出按指标绝对相关性排序的表与correlation.png热力图见correlation_analysiskprofile.py。三、从 YAML 清单生成检入的调优表3.1 清单manifest的角色kprofile分析完基准测试后会把选中的配置写入 YAML。对于检入的分发表dispatch table来说这个 YAML 就是manifest——一份需要出现在 Mojo 代码中的、有序的配置列表。真实的 manifest 示例见 tuning_table_sm100_bf16.yaml文件顶部通过defaults: defaults锚点集中声明共享参数如MMA_K: 16、CTA_GROUP: 2、SWAP_AB: false、各流水线阶段数等params列表中的每个条目用: *defaults合并锚点再覆盖该条目的独有参数M、N、K、MMA_M、MMA_N、CLUSTER_X等。这种结构让清单既紧凑又易读共享配置只维护一份条目之间只需比较差异。3.2 生成机制snippet 占位符 标记tuning_codegen是把 manifest 变成检入 Mojo 的受支持路径supported path。它的核心机制分为三步对应 tuning_codegen.py 中的函数渲染renderrender_snippet读取一个 snippet 模板将其中所有[NAME]形式的占位符替换为 manifest 条目中的对应值。若 snippet 中存在 manifest 未提供的占位符会直接报错Missing snippet parameters: ...避免生成残缺代码布尔值按True/False输出None输出为None见 tuning_codegen.py。区域生成render_region每个条目渲染结果前会追加两行溯源注释# Automatically generated from [source_label]与# index: [N]默认以 8 个空格缩进默认indent 并以逗号结尾见 tuning_codegen.py。区域替换replace_generated_region在目标 Mojo 文件中找到唯一的begin_marker与end_marker行替换两者之间的全部内容。标记必须恰好出现一次且 begin 先于 end否则抛错从机制上杜绝误替换见 tuning_codegen.py。每个 manifest 都有一个主 snippetprimary snippet。当一张表内混有多种 Mojo 构造器形态时条目可以通过_template字段指定使用某个 snippet 变体若所有条目形态一致则只用主 snippet 即可。--snippet-variant NAMEPATH可重复传入为每个变体注册模板文件render_region中若_template引用了未注册的变体会报unknown template错误。以 SM100 BF16 为例其 snippet 模板 tuning_sm100.mojo.snippet 形如TuningConfigSM100( M[M], M_end[M_END], N[N], K[K], mma_shapeIndex([MMA_M], [MMA_N], [MMA_K]), cta_group[CTA_GROUP], cluster_shapeIndex([CLUSTER_X], [CLUSTER_Y], [CLUSTER_Z]), block_swizzle_size[BLOCK_SWIZZLE_SIZE], rasterize_orderRasterOrder([RASTERIZE_ORDER]), swapAB[SWAP_AB], k_group_size[K_GROUP_SIZE], num_accum_pipeline_stages[NUM_ACCUM_PIPELINE_STAGES], num_clc_pipeline_stages[NUM_CLC_PIPELINE_STAGES], num_split_k[NUM_SPLIT_K], num_pipeline_stages[NUM_PIPELINE_STAGES], is_small_bn[IS_SMALL_BN], batch_size[BATCH_SIZE], )清单中的MMA_K、CTA_GROUP等参数会与 snippet 中的[...]占位符一一对应render_snippet也支持#注释行因此模板中可保留被注释掉的字段作为文档。单元测试 tests/test_tuning_codegen.py 验证了render_snippet的格式化布尔输出为True与缺失参数报错行为并验证了 manifest 保序、重复条目报错、标记唯一性约束、_template变体选择以及端到端的generate_target渲染结果。四、完整的调优表工作流原文档给出了从结果分析到代码落库的五步标准流程此处结合真实文件路径逐步展开。步骤 1在 kbench 输出上运行 kprofile 生成/更新 YAML manifestkprofile output.pkl -o tuning_table_sm100_bf16kprofile会把选中配置写入tuning_table_sm100_bf16.yaml--output指定文件名实际写盘时会以.yaml后缀落盘见codegen_yamlkprofile.py同时打印 common 列、pivot 列与条目数。若已存在旧 manifest可直接覆盖更新也可以结合--top、--head等筛选条件控制写入的配置集。步骤 2审阅选中的配置打开生成的 YAML核对每个条目的参数是否合理共享参数是否收敛、params顺序是否符合预期顺序会被原样保留进 Mojo 表、是否存在冗余或重复条目tuning_codegen的load_manifest会对重复条目直接报错见 tuning_codegen.py。步骤 3运行 tuning_codegen 更新被标记的 Mojo 区域以 SM100 BF16 表为例完整命令如下./bazelw run //max/kernels/benchmarks/autotune:tuning_codegen -- \ --manifest max/kernels/src/linalg/matmul/gpu/sm100_structured/default/tuning_table_sm100_bf16.yaml \ --snippet max/kernels/src/linalg/matmul/gpu/sm100_structured/default/tuning_sm100.mojo.snippet \ --target max/kernels/src/linalg/matmul/gpu/sm100_structured/default/tuning_configs.mojo \ --begin-marker BEGIN-TUNING-LIST-SM100-BF16 \ --end-marker END-TUNING-LIST-SM100-BF16 \ --source-label tuning_table_sm100_bf16.yaml各参数含义参数说明--manifestYAML 清单路径即上一步 kprofile 生成的文件--snippet主 snippet 路径逐条目展开的 Mojo 模板--target检入的 Mojo 目标文件其中包含待替换的标记区域--begin-marker/--end-marker标记区域的开头/结尾唯一文本二者之间会被整体替换--source-label写入生成注释的清单标签用于溯源--snippet-variant可选NAMEPATH形式可重复配合条目_template使用--check校验模式只报告 diff 不写盘若区域过期则以非零退出码失败目标文件 tuning_configs.mojo 内以BEGIN-TUNING-LIST-SM100-BF16/END-TUNING-LIST-SM100-BF16圈定的区域会被重新生成每个条目渲染结果形如# Automatically generated from [tuning_table_sm100_bf16.yaml] # index: [0] TuningConfigSM100(M256, M_end320, N20480, K5376, ...),--check模式的实现位于 tuning_codegen.py它先在内存中生成期望内容与当前文件内容比对不一致时通过difflib.unified_diff输出差异并触发SystemExit使 CI 能够捕获检入区域过期的问题。步骤 4格式化./bazelw run //:format代码生成后统一跑一次仓库级格式化确保生成的区域与手写代码风格一致、diff 干净。步骤 5运行该表的新鲜度测试./bazelw test \ //max/kernels/benchmarks/autotune:sm100_bf16_tuning_codegen_test该测试以--check方式运行tuning_codegen在内存中重新生成区域并对比检入的 Mojo若不一致即失败。其 Bazel 定义见 BUILD.bazel除了 BF16 表仓库还为 FP8、NVFP4、MXFP4、MXFP8、batched、small-MN 以及 SM90 等多张表分别注册了sm100_*_tuning_codegen_test、sm90_bf16_tuning_codegen_test等测试其中涉及多种构造器形态的表会通过--snippet-variant传入多个模板如 SM90 的custom、custom_grid、custom_scaled、custom_scaled_grid见 BUILD.bazel。调优清单与测试数据的依赖统一由tuning_codegen_table_datafilegroup 声明任何新增表格只需按同样模式补充 manifest、snippet 与测试目标即可接入这套流水线。五、小结kprofile与tuning_codegen的组合为 Mojo/MAX 的内核调优提供了一条可审计、可复现、可自动化的流水线kbench产出原始pkl→kprofile用多种视角top%、比值表、head/tail、diff、相关性、YAML 合并查询筛选出最优配置并固化为 YAML manifest →tuning_codegen依据 manifest 与 snippet 模板在唯一标记之间确定性渲染出带溯源注释的 Mojo 调优表 → 格式化与--check新鲜度测试守护检入区域的同步。整个过程以 YAML 清单为唯一事实来源single source of truth生成的代码可随时重新生成、可 diff、可测试非常适合在多 GPU 架构SM90、SM100与多数据类型BF16、FP8、MXFP4 等间持续维护大规模调优配置。【免费下载链接】mojoThe Modular Platform (includes MAX Mojo)项目地址: https://gitcode.com/GitHub_Trending/mo/mojo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表