RFC:在 speculators 上微调 DeepSeek-V4-Flash 的 DSpark 投机层
目标
对 DeepSeek 官方发布的 deepseek-ai/DeepSeek-V4-Flash-DSpark 投机层进行微调(fine-tune) ,使用 speculators 的 DSpark 算法路径。DSv4-Flash 的 DSpark 是 self-drafting(draft 复用 target 自身层),target 层是 MoE,因此 draft 天然含 MoE experts——满足"MoE 投机层"需求。
背景事实(已核实)
DSv4-Flash 与 DSpark
speculators 现状(代码证据,commit f8cf626 )
DSpark 在本仓库继承 DFlash,draft 层硬编码 dense,未适配 DSv4:
src/speculators/models/dspark/core.py:21-22 —— DSparkDraftModel(DFlashDraftModel),__init__ 调 super().__init__(core.py:33),复用 DFlash 的 layer 构造。
src/speculators/models/dflash/core.py:78-83 —— draft 层硬编码 Qwen3DFlashDecoderLayer,无 layer 注册/分发。
src/speculators/models/dflash/model_definitions.py:158,163 —— Qwen3DFlashDecoderLayer.mlp = Qwen3MLP(dense),attention 为 Qwen3DFlashAttention(标准 GQA,非 MLA)。
DSpark 相比 DFlash 仅多 MarkovHead(dspark/model_definitions.py:12-81)+ ConfidenceHead(model_definitions.py:83-91),draft 层结构完全相同,dense 。
src/speculators/models/dspark/ 与 dflash/ 下 hc_mult|hc_head|mHC|dsv4|deepseek 零代码命中 (仅 dspark/config.py:36 一句无关注释)。DSv4 的 mHC 未适配。
scripts/train.py:50-53 —— DRAFT_ARCH_CONFIGS = {"llama": LlamaConfig, "qwen3": Qwen3Config},from-scratch 路径只产出 dense。
src/speculators/convert/ 下只有 dflash / eagle / mtp,无 dspark converter (entrypoints.py:22-24, 140-142)。
微调已有 checkpoint 的现有路径
scripts/train.py:446-459 的 --from-pretrained(非 config-only、非 mtp)分支 → SpeculatorModel.from_pretrained(src/speculators/model.py:232-388):可加载 speculators 原生格式 (config.json 含 speculators_model_type="dspark" + safetensors)的 DSpark checkpoint 并继续训练。
但官方 DeepSeek-V4-Flash-DSpark 不是 speculators 原生格式 ,而是 DeepSpec/vLLM 的 self-drafting 格式(draft 权重嵌在 target checkpoint 里,按 dspark_target_layer_ids 复用 target 层)。speculators 没有把它转成原生格式的 converter。
需要的改造
A. 加载官方 DSpark checkpoint(最关键,决定能否微调)
新建 dspark converter :在 src/speculators/convert/dspark/ 新增 converter(注册到 entrypoints.py:22-24, 32, 140-142),从 DeepSeek-V4-Flash-DSpark checkpoint 抽取 DSpark draft 权重,转成 speculators 原生格式。需处理:
self-drafting 的权重布局:draft 权重在 target checkpoint 里的 key 前缀与 speculators 的 DSparkSpeculator 期望布局(dspark/config.py:23-26 的 architectures=["DSparkSpeculator"])之间的映射。
dspark_target_layer_ids: [40,41,42] → speculators DSpark 的 layer 数(DFlash/DSpark 的 num_draft_layers,见 dflash/core.py:78-83)。
dspark_block_size: 5 → DSpark config 的 block_size(dspark/config.py 继承 DFlash 的 block_size)。
dspark_noise_token_id → DSpark 的 noise/mask token。
参考 convert/mtp/converter.py 的抽取+fuse 模式,但 DSpark 无 mtp.* 前缀,权重来自 target 层复用。
B. 让 DSpark draft 层支持 MoE(对齐 DSv4 self-drafting 的 MoE 结构)
新建 MoE DFlash decoder layer :参照 dflash/model_definitions.py:158-207 的 Qwen3DFlashDecoderLayer,把 self.mlp = Qwen3MLP(第 163 行)换成 DSv4 的 MoE block(256 routed + 1 shared expert,aux-loss-free 路由,FP4 expert)。attention 部分需从 Qwen3DFlashAttention(GQA)换成 DSv4 MLA(CSA+HCA) 的 DFlash 变体。
让 DSpark 用该 layer :DFlashDraftModel.__init__(dflash/core.py:78-83)当前硬编码 Qwen3DFlashDecoderLayer,需改为按 model_type 分发(对齐 eagle3/model_definitions.py:131-137 的注册制),或 DSpark 覆盖 __init__。同步更新 _no_split_modules(dflash/core.py:36)。
C. 适配 DSv4 的 mHC 与 MLA
mHC(hc_mult=4) :DSv4 hidden state 是 hc_mult * hidden_size。需在 DSpark/DFlash 里加 hc_head_project 折叠 hc_mult*hidden_size → hidden_size(参考 Add hc_mult support to DFlash for DeepSeek-V4-Flash vllm-project/speculators#524 给 dense DFlash 的 mHC 适配,但 Add hc_mult support to DFlash for DeepSeek-V4-Flash vllm-project/speculators#524 尚未合入 main)。DSpark 的 MarkovHead/ConfidenceHead 输入维度也要相应对齐。
MLA :Qwen3DFlashAttention 假设标准 GQA + hidden_size 形状的 target_hidden。DSv4 用 MLA + hc_mult*hidden_size,K/V 构造需重写(风险最高)。
D. 训练侧
config 注册 :DRAFT_ARCH_CONFIGS(scripts/train.py:50-53)加 DSv4 条目;create_transformer_layer_config(train.py:178-194)支持构造含 n_routed_experts / num_experts_per_tok / hc_mult / q_lora_rank 等字段的 config。
MoE aux loss :dspark/metrics.py / dspark/core.py:187-199 的 loss 当前无 router aux loss,需加入(DSv4 是 aux-loss-free 路由,可能不需要传统 load-balance loss,需对照 DeepSpec 实现)。
数据生成 :src/speculators/train/data.py hidden state 抽取架构无关,但 DSv4 的 mHC hidden state 形状(hc_mult*hidden_size)需在 dataloader 里处理(参考 Add hc_mult support to DFlash for DeepSeek-V4-Flash vllm-project/speculators#524 的 hc_mult 透传到 collate/sample 形状)。
vllm-project#524 给 dense DFlash 加 DSv4 mHC 适配(hc_mult 透传、hc_head_project、load_verifier_weights override),尚未合入 main。本 issue 的 DSpark MoE 路径应建立在 vllm-project#524 的 mHC 适配之上,但额外需要:MoE layer、MLA attention、dspark converter、self-drafting 权重抽取——范围远大于 vllm-project#524 。
开放问题
是否应直接用 DeepSpec 微调? DeepSeek 官方 github.com/deepseek-ai/DeepSpec 已提供 DSpark 训练流水线且原生支持 DSv4-Flash。若目标只是微调 DSv4-Flash-DSpark,DeepSpec 可能比改造 speculators 更直接。本 issue 的价值在于:把 DSv4-Flash DSpark 纳入 speculators 的统一 draft 训练框架(与 EAGLE-3/DFlash/MTP 一致的 config/数据/部署契约)。需讨论是否值得。
self-drafting vs 独立 draft :DSv4-Flash-DSpark 是 self-drafting(draft=target 层)。speculators 的 DSpark 是独立 dense draft。微调时是保持 self-drafting(draft 层=target MoE 层)还是改成独立 MoE draft?前者更贴近官方、改造在 converter;后者更通用、改造在 layer 注册。倾向前者。
MoE draft 在 DSv4 上的接受率 :self-drafting draft=target 层理论上接受率高(与 target 同构),但 mHC+MLA+FP4 expert 的训练稳定性需小规模验证(DSv4-Lite 或减少 expert 数)。
expert FP4 训练 :DSv4 expert 是 FP4,微调时是否保持 FP4?speculators 的 trainer(src/speculators/train/trainer.py)当前 dense-only,FP4 MoE 训练需额外支持。
RFC:在 speculators 上微调 DeepSeek-V4-Flash 的 DSpark 投机层
目标
对 DeepSeek 官方发布的
deepseek-ai/DeepSeek-V4-Flash-DSpark投机层进行微调(fine-tune),使用 speculators 的 DSpark 算法路径。DSv4-Flash 的 DSpark 是 self-drafting(draft 复用 target 自身层),target 层是 MoE,因此 draft 天然含 MoE experts——满足"MoE 投机层"需求。背景事实(已核实)
DSv4-Flash 与 DSpark
deepseek-ai/DeepSeek-V4-Flash,284B 参数 / 13B activated,1M 上下文。基础版原生带 MTP(num_nextn_predict_layers: 1),不自带 DSpark。deepseek-ai/DeepSeek-V4-Flash-DSpark是"同一 checkpoint 附加了一个投机解码模块"(官方卡片原文)。配置含dspark_block_size: 5、dspark_target_layer_ids: [40,41,42]、dspark_noise_token_id: 128799。github.com/deepseek-ai/DeepSpec,含 DSpark/DFlash/Eagle3 三种 draft。DeepSpec README 明确建议 domain-specific 场景"fine-tune the draft model again"。n_routed_experts: 256、n_shared_experts: 1、num_experts_per_tok: 6,expert FP4)+ mHC(hc_mult: 4)+ MLA(CSA+HCA,num_key_value_heads: 1、q_lora_rank: 1024),hidden_size: 4096,num_hidden_layers: 43。vllm serve deepseek-ai/DeepSeek-V4-Flash-DSpark --speculative_config '{"method":"dspark","num_speculative_tokens":5}'。本 issue 不涉及推理侧。speculators 现状(代码证据,commit f8cf626)
DSpark 在本仓库继承 DFlash,draft 层硬编码 dense,未适配 DSv4:
src/speculators/models/dspark/core.py:21-22——DSparkDraftModel(DFlashDraftModel),__init__调super().__init__(core.py:33),复用 DFlash 的 layer 构造。src/speculators/models/dflash/core.py:78-83—— draft 层硬编码Qwen3DFlashDecoderLayer,无 layer 注册/分发。src/speculators/models/dflash/model_definitions.py:158,163——Qwen3DFlashDecoderLayer.mlp = Qwen3MLP(dense),attention 为Qwen3DFlashAttention(标准 GQA,非 MLA)。MarkovHead(dspark/model_definitions.py:12-81)+ConfidenceHead(model_definitions.py:83-91),draft 层结构完全相同,dense。src/speculators/models/dspark/与dflash/下hc_mult|hc_head|mHC|dsv4|deepseek零代码命中(仅dspark/config.py:36一句无关注释)。DSv4 的 mHC 未适配。scripts/train.py:50-53——DRAFT_ARCH_CONFIGS = {"llama": LlamaConfig, "qwen3": Qwen3Config},from-scratch 路径只产出 dense。src/speculators/convert/下只有dflash / eagle / mtp,无 dspark converter(entrypoints.py:22-24, 140-142)。微调已有 checkpoint 的现有路径
scripts/train.py:446-459的--from-pretrained(非 config-only、非 mtp)分支 →SpeculatorModel.from_pretrained(src/speculators/model.py:232-388):可加载 speculators 原生格式(config.json 含speculators_model_type="dspark"+ safetensors)的 DSpark checkpoint 并继续训练。DeepSeek-V4-Flash-DSpark不是 speculators 原生格式,而是 DeepSpec/vLLM 的 self-drafting 格式(draft 权重嵌在 target checkpoint 里,按dspark_target_layer_ids复用 target 层)。speculators 没有把它转成原生格式的 converter。需要的改造
A. 加载官方 DSpark checkpoint(最关键,决定能否微调)
src/speculators/convert/dspark/新增 converter(注册到entrypoints.py:22-24, 32, 140-142),从DeepSeek-V4-Flash-DSparkcheckpoint 抽取 DSpark draft 权重,转成 speculators 原生格式。需处理:DSparkSpeculator期望布局(dspark/config.py:23-26的architectures=["DSparkSpeculator"])之间的映射。dspark_target_layer_ids: [40,41,42]→ speculators DSpark 的 layer 数(DFlash/DSpark 的num_draft_layers,见dflash/core.py:78-83)。dspark_block_size: 5→ DSpark config 的block_size(dspark/config.py继承 DFlash 的block_size)。dspark_noise_token_id→ DSpark 的 noise/mask token。convert/mtp/converter.py的抽取+fuse 模式,但 DSpark 无mtp.*前缀,权重来自 target 层复用。B. 让 DSpark draft 层支持 MoE(对齐 DSv4 self-drafting 的 MoE 结构)
dflash/model_definitions.py:158-207的Qwen3DFlashDecoderLayer,把self.mlp = Qwen3MLP(第 163 行)换成 DSv4 的 MoE block(256 routed + 1 shared expert,aux-loss-free 路由,FP4 expert)。attention 部分需从Qwen3DFlashAttention(GQA)换成 DSv4 MLA(CSA+HCA) 的 DFlash 变体。DFlashDraftModel.__init__(dflash/core.py:78-83)当前硬编码Qwen3DFlashDecoderLayer,需改为按model_type分发(对齐eagle3/model_definitions.py:131-137的注册制),或 DSpark 覆盖__init__。同步更新_no_split_modules(dflash/core.py:36)。C. 适配 DSv4 的 mHC 与 MLA
hc_mult=4):DSv4 hidden state 是hc_mult * hidden_size。需在 DSpark/DFlash 里加hc_head_project折叠hc_mult*hidden_size → hidden_size(参考 Add hc_mult support to DFlash for DeepSeek-V4-Flash vllm-project/speculators#524 给 dense DFlash 的 mHC 适配,但 Add hc_mult support to DFlash for DeepSeek-V4-Flash vllm-project/speculators#524 尚未合入 main)。DSpark 的MarkovHead/ConfidenceHead输入维度也要相应对齐。Qwen3DFlashAttention假设标准 GQA +hidden_size形状的target_hidden。DSv4 用 MLA +hc_mult*hidden_size,K/V 构造需重写(风险最高)。D. 训练侧
DRAFT_ARCH_CONFIGS(scripts/train.py:50-53)加 DSv4 条目;create_transformer_layer_config(train.py:178-194)支持构造含n_routed_experts / num_experts_per_tok / hc_mult / q_lora_rank等字段的 config。dspark/metrics.py/dspark/core.py:187-199的 loss 当前无 router aux loss,需加入(DSv4 是 aux-loss-free 路由,可能不需要传统 load-balance loss,需对照 DeepSpec 实现)。src/speculators/train/data.pyhidden state 抽取架构无关,但 DSv4 的 mHC hidden state 形状(hc_mult*hidden_size)需在 dataloader 里处理(参考 Add hc_mult support to DFlash for DeepSeek-V4-Flash vllm-project/speculators#524 的hc_mult透传到 collate/sample 形状)。与 vllm-project#524 的关系
vllm-project#524 给 dense DFlash 加 DSv4 mHC 适配(
hc_mult透传、hc_head_project、load_verifier_weightsoverride),尚未合入 main。本 issue 的 DSpark MoE 路径应建立在 vllm-project#524 的 mHC 适配之上,但额外需要:MoE layer、MLA attention、dspark converter、self-drafting 权重抽取——范围远大于 vllm-project#524。开放问题
github.com/deepseek-ai/DeepSpec已提供 DSpark 训练流水线且原生支持 DSv4-Flash。若目标只是微调 DSv4-Flash-DSpark,DeepSpec 可能比改造 speculators 更直接。本 issue 的价值在于:把 DSv4-Flash DSpark 纳入 speculators 的统一 draft 训练框架(与 EAGLE-3/DFlash/MTP 一致的 config/数据/部署契约)。需讨论是否值得。src/speculators/train/trainer.py)当前 dense-only,FP4 MoE 训练需额外支持。