Prhub

#50524 [Model] Add K-EXAONE-2.0-750B-A37B

原始 PR 作者 lkm2835 合并时间 2026-08-03 21:33 文件变更 6 提交数 4 评论 4 代码增减 +161 / -11

执行摘要

新增 K-EXAONE-2.0-750B-A37B 模型支持

PR body 明确说明目的是支持 LG AI Research 开发的 K-EXAONE-2.0-750B-A37B,并附上了 HuggingFace、技术报告、Transformers、SGLang 与 Megatron-Bridge 的参考链接。相比已有 K-EXAONE-236B-A23B,新模型引入了 mlp_layer_types(sparse/dense 混合)、swiglu_limits(逐层 clamp)、layer_types 与 mtp_layer_types(滑动窗口/全注意力混合)等新配置项,原有 ExaoneMoE 实现无法直接覆盖这些配置,需要在模型结构层适配。

值得精读,尤其是 exaone_moe.py 中注意力层与 MLP 路由的适配方式。该 PR 展示了如何在一个既有模型实现中扩展新配置:保持向后兼容(默认参数)的同时引入新分支。可重点学习 swiglu_limit 的逐层传递模式与 set_default_rope_theta 的用法。不过对于团队,建议关注模型注册名大小写变更的沟通,以及后续补充针对 K-EXAONE-2.0 的 e2e 测试。

讨论亮点

Review 中唯一实质讨论来自维护者 DarkLight1337:在 docs/models/supported_models.md 中,他建议将两行架构名相同的表格行合并(原 diff 拆成了 K-EXAONE 与 K-EXAONE-2 两行),理由是“as the arch name is the same”。作者 lkm2835 回复“Thanks, I merged it”并完成合并。另外,作者在 issue 评论中请求重跑失败 checks,原因是 HF config.json 已更新,说明 CI 失败与上游配置文件变更有关,并非实现缺陷。

实现拆解

实现按以下步骤拆解:

  1. 独立 MoE 注意力实现vllm/model_executor/models/exaone_moe.py):不再从 exaone4.py 导入 Exaone4Attention,而是新增 ExaoneMoeAttention 类。该类包含 qkv_proj / o_proj、q_norm / k_norm、旋转位置编码、per-layer 滑动窗口判断(基于 config.layer_typesconfig.mtp_layer_types),并支持 is_mtp 参数区分 MTP 层。新增 set_default_rope_theta(config, default_theta=1000000) 保证 rope theta 默认值与 HF 对齐。
  2. 逐层 swiglu clamp 支持:在 exaone_moe.pyExaoneMoeDecoderLayer 中读取 config.swiglu_limits[layer_idx],若大于 0 则传入 ExaoneMoeExaoneMoeGatedMLPexaone4.pyExaone4GatedMLP 新增 swiglu_limit 参数,根据该值选择 SiluAndMulSiluAndMulWithClamp
  3. MLP 层类型路由改造ExaoneMoeDecoderLayer.__init__ 中原来用 config.is_moe_layer[layer_idx] 判断是否为 MoE 层,改为 config.mlp_layer_types[layer_idx] == "sparse",以匹配新模型配置。
  4. MTP 层参数统一exaone_moe_mtp.py 中将 mtp_layer 参数重命名为 is_mtp,与 ExaoneMoeAttention 的构造参数保持一致。
  5. 注册与文档配套registry.pytests/models/registry.pyExaoneMoEForCausalLM 统一改为 ExaoneMoeForCausalLMdocs/models/supported_models.md 更新架构行为 K-EXAONE, K-EXAONE-2,列出新模型路径。测试代码未新增用例,仅同步注册名,因为现有 K-EXAONE 测试已覆盖同一实现路径。
文件 模块 状态 重要度
vllm/model_executor/models/exaone_moe.py 模型实现 modified 8.67
vllm/model_executor/models/exaone4.py 模型实现 modified 6.18
vllm/model_executor/models/exaone_moe_mtp.py 模型实现 modified 4.7
vllm/model_executor/models/registry.py 模型注册 modified 5.1
tests/models/registry.py 模型测试 modified 3.63
docs/models/supported_models.md 模型文档 modified 1.93

关键符号

ExaoneMoeAttention.__init__ ExaoneMoeAttention.forward ExaoneMoe.__init__ ExaoneMoeDecoderLayer.__init__ Exaone4GatedMLP.__init__

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

评论区精华

supported_models.md 表格行合并 documentation

DarkLight1337 评论:"Let's merge these two rows together as the arch name is the same",指出新模型与已有 K-EXAONE 是同一架构,应合并为一行。

结论:作者 lkm2835 回复 "Thanks, I merged it",并实际合并了表格行。 · 已解决

重跑失败的 CI checks question

作者在 issue 评论中请求维护者重跑失败检查,原因是 HF 上现有 K-EXAONE-236B-A22B 的 config.json 已更新。

结论:未在评论中直接看到维护者回复,但从最终合并状态看,CI 最终通过。 · closed

风险与影响

技术风险集中在以下三点:

  • 注册名变更风险ExaoneMoEForCausalLM 改为 ExaoneMoeForCausalLM 属于公开 model registry 的键名变更,任何依赖旧名字的脚本或用户配置将无法加载模型。虽然 HF 官方架构名是后者,但迁移应视为 breaking change,需在文档中明确提示。
  • MLP 层路由逻辑变更config.is_moe_layer 改为 config.mlp_layer_types,若旧 EXAONE 配置同时包含两者但取值不一致,可能改变层类型判断结果。现有 K-EXAONE-236B-A23B 测试能覆盖该路径,但未新增针对新模型的 e2e 测试,存在回归盲区。
  • swiglu_limits 读取swiglu_limits 为列表时逐层索引取值,若配置缺失或长度与层数不匹配会抛异常;代码中对非正数做了 None 回退,但未处理索引越界。
  • 注意力层逻辑复杂度ExaoneMoeAttention 增加了 sliding_window_size / mtp_sliding_window 分支,涉及多个配置键组合,缺少针对 MTP + 滑动窗口组合的单元测试,潜在边界条件未被覆盖。

影响范围:

  • 用户侧:使用 K-EXAONE 系列模型的用户可用 LGAI-EXAONE/K-EXAONE-2.0-750B-A37B 直接加载推理;但模型注册名变更需用户更新代码中的架构名引用。
  • 系统侧:改动集中在模型实现层,不触碰调度器、KV cache、分布式等核心路径,对现有非 EXAONE 模型无影响;exaone4.py 新增 swiglu_limit 参数为可选,默认行为不变。
  • 团队侧:该 PR 为后续 EXAONE 新版本(可能有更多层类型组合)奠定了基础,但当前缺少面向新模型的额外测试,维护者需依赖上游 HF 测试或社区反馈。
模型注册名变更(MoE→Moe) MLP 层路由逻辑变更 缺少新模型 e2e 测试 swiglu_limits 索引越界风险

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论