01_DeepSpec-DSpark-整体架构与设计理念
01 · 整体架构与设计理念
本篇在总分总中承上启下:00 总览 给出项目地图,02 核心原理 与 05 数据管道 已讲清"为什么"和"数据从哪来",本篇回答"代码怎么组织"——分层架构、配置驱动、统一抽象、三算法共用基础设施的设计哲学。
总览段(总)
DeepSpec 的设计理念可凝练为一句话:把"为任意 target 训练 speculative draft 模型"这件事抽象成可替换的三件套——config 选择算法、modeling 实现算法、trainer/evaluator 编排算法。三算法(DSpark / DFlash / Eagle3)共用同一套 BaseTrainer / BaseEvaluator / CacheDataset / BF16Optimizer / CUDAPrefetcher 基础设施,差异集中在 modeling + loss 层。
图说明: 入口层只做参数解析与 spawn,业务逻辑全部下沉到 core 库。config 文件作为"算法身份证"——train.trainer_cls 字段决定用哪个 trainer,architectures 决定 eval 时用哪个 evaluator。所有 trainer 都派生自 BaseTrainer,所有 evaluator 派生自 BaseEvaluator,这是 DeepSpec 工程化的基石。
分述段(分)
1.1 分层架构
DeepSpec 严格分五层,自下而上依赖:
| 层 | 路径 | 职责 | 依赖 |
|---|---|---|---|
| utils | deepspec/utils/ | config / distributed / io / metrics / optim / sampling / logger | torch |
| data | deepspec/data/ | target cache + jsonl + parser + cuda_prefetcher | utils |
| modeling | deepspec/modeling/{dspark,eagle3}/ | draft 模型定义 + loss | utils |
| trainer/eval | deepspec/trainer/ deepspec/eval/ | 训练/评测编排 | data + modeling + utils |
| scripts | scripts/{train,eval,data}/ | shell 编排 + 数据准备 | trainer/eval/data |
1.2 入口层:策略模式驱动
[train.py](file:///workspace/train.py) 极简(45 行),核心是这两行:
trainer = args.train.trainer_cls(local_rank, args) # train.py:36
trainer.train()
trainer_cls 字段在 config 中指定(如 Qwen3DSparkTrainer),入口层不感知算法。parse_opts_to_config([utils/config.py:113-131](file:///workspace/deepspec/utils/config.py#L113-131))支持 --opts "a.b.c=value" 路径式覆盖任意配置字段,让超参实验零代码改动。
[eval.py](file:///workspace/eval.py) 用 draft_config.architectures[0] 在 EVALUATORS 字典中路由([eval.py:10-16](file:///workspace/eval.py#L10-16)):
EVALUATORS = {
"Qwen3DSparkModel": Qwen3DSparkEvaluator,
"Gemma4DSparkModel": Gemma4DSparkEvaluator,
"Qwen3Eagle3Model": Qwen3Eagle3Evaluator,
"Gemma4Eagle3Model": Gemma4Eagle3Evaluator,
"Eagle3DraftModel": Qwen3Eagle3Evaluator,
}
这种"配置即类型"的设计让训练好的 draft checkpoint 可直接被 eval 识别——加载时读 config.json 的 architectures 字段即可路由。
1.3 三算法统一抽象
图说明: BaseTrainer([base_trainer.py:148](file:///workspace/deepspec/trainer/base_trainer.py#L148))抽象了训练循环的全部骨架:分布式初始化、FSDP 包装、cache 校验、梯度累积、optimizer step、checkpoint 保存、hfai 抢占处理。子类只需实现 _build_draft_model(构造哪种 draft)和 run_batch(怎么算 loss)。BaseEvaluator([base_evaluator.py:444-728](file:///workspace/deepspec/eval/base_evaluator.py#L444-728))抽象了推测解码评测的全部骨架:拒绝采样 verify_draft_tokens、generate_decoding_sample 循环、跨 rank allreduce、指标计算。子类只需实现 _init_context / _propose / _update 三个钩子。DFlash 没有专属 trainer——它复用 Qwen3DSparkTrainer,只是 config 不同。
1.4 关键发现:DFlash 是 DSpark 的退化配置
对比三个 config 文件揭示一个重要事实:
| 字段 | DSpark | DFlash | Eagle3 |
|---|---|---|---|
trainer_cls | Qwen3DSparkTrainer | Qwen3DSparkTrainer | Qwen3Eagle3Trainer |
block_size / ttt_length | 7 / - | 7 / - | - / 7 |
markov_rank | 256 | 0 | - |
confidence_head_alpha | 1.0 | 0.0 | - |
ce_loss_alpha | 0.1 | 1.0 | - |
l1_loss_alpha | 0.9 | 0.0 | - |
DFlash 的 config([config/dflash/dflash_qwen3_4b.py](file:///workspace/config/dflash/dflash_qwen3_4b.py))禁用 Markov head、禁用 confidence head、用纯 CE 损失,复用 Qwen3DSparkTrainer。这意味着 DeepSpec 把 DFlash 视为 DSpark 的一个特例——关闭 DSpark 的两项创新即得到 DFlash。这是优秀的算法族抽象。
1.5 配置层结构
所有 config 文件都是 Python 模块,顶层定义 5 个 dict + 1 个 finalize_cfg 函数。以 [config/dspark/dspark_qwen3_4b.py](file:///workspace/config/dspark/dspark_qwen3_4b.py) 为例:
project_name = "deepspec" # 项目名(决定 checkpoint 路径)
exp_name = "dspark_block8_qwen3_4b"
seed = 42
model = dict(target_model_name_or_path=..., block_size=7, ...)
train = dict(trainer_cls=Qwen3DSparkTrainer, lr=6.0e-4, ...)
logging = dict(logging_steps=10, checkpointing_steps=3000)
data = dict(target_cache_path=None, chat_template="qwen", max_length=4096, ...)
def finalize_cfg(cfg):
# 根据 project_name/exp_name 拼接 checkpoint_dir 和 tensorboard_dir
...
[load_config](file:///workspace/deepspec/utils/config.py) 用 importlib.util 动态加载 Python config 文件,收集模块所有非下划线变量([utils/config.py:84-98](file:///workspace/deepspec/utils/config.py#L84-98))。finalize_cfg 在加载后调用,用于派生路径字段。
1.6 utils 层:通用基础设施
| 文件 | 作用 |
|---|---|
| [config.py](file:///workspace/deepspec/utils/config.py) | ConfigNode dict + load_config + parse_opts_to_config |
| [distributed.py](file:///workspace/deepspec/utils/distributed.py) | init_dist NCCL + StatelessResumableDistributedSampler 跨 epoch 流式 |
| [io.py](file:///workspace/deepspec/utils/io.py) | ensure_dir + safe_symlink 原子符号链接 |
| [metrics.py](file:///workspace/deepspec/utils/metrics.py) | 全局 metric 收集器,支持 ratio/scalar,dp_sum 默认 |
| [optim.py](file:///workspace/deepspec/utils/optim.py) | BF16Optimizer + CosineAnnealingWarmupLR + TwoStageScheduler |
| [sampling.py](file:///workspace/deepspec/utils/sampling.py) | logits_to_probs / sample_tokens / sample_residual |
| [training_logger.py](file:///workspace/deepspec/utils/training_logger.py) | SummaryWriter 单例 + 进度打印 |
| [hfai_suspend.py](file:///workspace/deepspec/utils/hfai_suspend.py) | HighFlyer AI 抢占式调度支持,无 hfai 时降级 no-op |
1.7 目录树与模块依赖
图说明: 依赖方向严格自上而下:utils 是叶子,data/modeling 依赖 utils,trainer/eval 依赖 data+modeling+utils,入口和脚本依赖 trainer/eval。eval_datasets 是数据资产,DSpark_paper.pdf 是参考文档。这种分层让任何一层都可单独测试与替换。
1.8 数据流:从 prompt 到 τ
图说明: 完整数据流从 HuggingFace 数据集到评测指标 τ。前 4 步在 05 数据管道 详述;中间 5 步在 06 训练框架 与 03 DSpark 建模 详述;最后 2 步在 07 评测系统 详述。每个箭头都对应一个具体文件,整条流水线无任何隐式耦合。
小结段(总)
DeepSpec 的架构精髓在"统一抽象 + 配置驱动":用 BaseTrainer / BaseEvaluator 把三算法的共性(分布式、FSDP、cache 读取、拒绝采样、指标聚合)抽到基类,子类只实现差异化的 _build_draft_model / run_batch / _propose / _update。这让新增算法的代价极小——DFlash 甚至不需要写新代码,只需一份退化 config。
设计理念总结为四点:
- 配置即算法身份证:
trainer_cls与architectures字段贯穿训练与评测,零 if-else 分支。 - 数据-模型-训练三解耦:target cache 让训练时不需要 target 模型,draft 模型与 loss 独立可换,trainer 编排逻辑与具体算法无关。
- 共用基础设施:FSDP、bf16 master、CUDA prefetcher、跨 epoch sampler、hfai 抢占支持——三算法共享一份工程实现。
- DFlash 是 DSpark 的退化:揭示了 Markov head 与 confidence head 是 DSpark 相对 DFlash 的全部增量,工程上验证了论文 Section 4.3.1 的"suffix decay 来自并行独立性"诊断。
易踩坑点:
- 切换 target 模型必须同时改 config 的
target_model_name_or_path、mask_token_id(Qwen3=151669,Gemma4 不同)、chat_template(qwen / gemma4)、target_layer_ids(层数对得上)。 --opts覆盖嵌套字段用点分路径:--opts "data.target_cache_path=/path",值用 Python 标量解析。- 评测时
architectures字段决定 evaluator,加载错误的 checkpoint 类型会 KeyError。
延伸阅读:进入 03 DSpark 建模 看 DSpark 如何在 Qwen3DSparkModel 中实现半自回归;进入 06 训练框架 看 BaseTrainer 的 10 步初始化。论文 Section 3.3(Training)描述了 DSpark 训练目标,见 [DSpark_paper.pdf](file:///workspace/DSpark_paper.pdf)。
更多推荐
所有评论(0)