09_DeepSpec-DSpark-使用指南_从零到评测

09 · 使用指南:从零到评测

本篇在总分总中是"分"的实操篇。前序 01 整体架构--08 实验复现 已讲清原理与代码,本篇给出可直接复制运行的端到端命令、5 个实战案例、自定义 target 接入流程与故障排查 FAQ。所有命令中的占位符用 <...> 标注,替换即可使用。


总览段(总)

DeepSpec 的使用分四步:环境安装 → 数据准备 → 训练 → 评测。前三步是一次性投入(38TB target cache 生成最重),后两步可反复迭代(改 config 训新算法、换 checkpoint 评测)。
#mermaid-svg-nZcWsJ5aekKdYPzL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-nZcWsJ5aekKdYPzL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-nZcWsJ5aekKdYPzL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-nZcWsJ5aekKdYPzL .error-icon{fill:#552222;}#mermaid-svg-nZcWsJ5aekKdYPzL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nZcWsJ5aekKdYPzL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-nZcWsJ5aekKdYPzL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nZcWsJ5aekKdYPzL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nZcWsJ5aekKdYPzL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-nZcWsJ5aekKdYPzL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nZcWsJ5aekKdYPzL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nZcWsJ5aekKdYPzL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nZcWsJ5aekKdYPzL .marker.cross{stroke:#333333;}#mermaid-svg-nZcWsJ5aekKdYPzL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nZcWsJ5aekKdYPzL p{margin:0;}#mermaid-svg-nZcWsJ5aekKdYPzL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-nZcWsJ5aekKdYPzL .cluster-label text{fill:#333;}#mermaid-svg-nZcWsJ5aekKdYPzL .cluster-label span{color:#333;}#mermaid-svg-nZcWsJ5aekKdYPzL .cluster-label span p{background-color:transparent;}#mermaid-svg-nZcWsJ5aekKdYPzL .label text,#mermaid-svg-nZcWsJ5aekKdYPzL span{fill:#333;color:#333;}#mermaid-svg-nZcWsJ5aekKdYPzL .node rect,#mermaid-svg-nZcWsJ5aekKdYPzL .node circle,#mermaid-svg-nZcWsJ5aekKdYPzL .node ellipse,#mermaid-svg-nZcWsJ5aekKdYPzL .node polygon,#mermaid-svg-nZcWsJ5aekKdYPzL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-nZcWsJ5aekKdYPzL .rough-node .label text,#mermaid-svg-nZcWsJ5aekKdYPzL .node .label text,#mermaid-svg-nZcWsJ5aekKdYPzL .image-shape .label,#mermaid-svg-nZcWsJ5aekKdYPzL .icon-shape .label{text-anchor:middle;}#mermaid-svg-nZcWsJ5aekKdYPzL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-nZcWsJ5aekKdYPzL .rough-node .label,#mermaid-svg-nZcWsJ5aekKdYPzL .node .label,#mermaid-svg-nZcWsJ5aekKdYPzL .image-shape .label,#mermaid-svg-nZcWsJ5aekKdYPzL .icon-shape .label{text-align:center;}#mermaid-svg-nZcWsJ5aekKdYPzL .node.clickable{cursor:pointer;}#mermaid-svg-nZcWsJ5aekKdYPzL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-nZcWsJ5aekKdYPzL .arrowheadPath{fill:#333333;}#mermaid-svg-nZcWsJ5aekKdYPzL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-nZcWsJ5aekKdYPzL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-nZcWsJ5aekKdYPzL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nZcWsJ5aekKdYPzL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-nZcWsJ5aekKdYPzL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nZcWsJ5aekKdYPzL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-nZcWsJ5aekKdYPzL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-nZcWsJ5aekKdYPzL .cluster text{fill:#333;}#mermaid-svg-nZcWsJ5aekKdYPzL .cluster span{color:#333;}#mermaid-svg-nZcWsJ5aekKdYPzL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-nZcWsJ5aekKdYPzL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-nZcWsJ5aekKdYPzL rect.text{fill:none;stroke-width:0;}#mermaid-svg-nZcWsJ5aekKdYPzL .icon-shape,#mermaid-svg-nZcWsJ5aekKdYPzL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nZcWsJ5aekKdYPzL .icon-shape p,#mermaid-svg-nZcWsJ5aekKdYPzL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-nZcWsJ5aekKdYPzL .icon-shape .label rect,#mermaid-svg-nZcWsJ5aekKdYPzL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nZcWsJ5aekKdYPzL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-nZcWsJ5aekKdYPzL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-nZcWsJ5aekKdYPzL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 换 config 重训
换 ckpt 重评
④ 评测 可反复迭代
选 9 benchmark 或子集
eval.sh
τ per benchmark
③ 训练 可反复迭代
选 config
train.sh
checkpoint step_latest
② 数据 准备一次性投入
download_and_split
launch_sglang + generate_train_data
prepare_target_cache
① 环境
pip install -r requirements.txt
sglang 单独装
8 GPU + 38TB 磁盘

图说明: 全流程的关键在"数据准备一次性投入"------38TB target cache 生成耗时数天,但生成后可被所有算法的训练复用(只要 target_layer_ids 一致)。训练与评测可快速迭代:改 --opts 训新超参、换 checkpoint 评测。


分述段(分)

9.1 环境安装

bash 复制代码
# 1. 安装 Python 依赖
python -m pip install -r requirements.txt

# 2. 单独安装 sglang(用于数据阶段的回答重生成)
pip install "sglang[all]"

# 3. 验证 GPU 数
nvidia-smi --list-gpus | wc -l   # 期望 8

requirements.txt 不含 sglang,因 sglang 版本与 CUDA 强耦合,需单独装。HuggingFace token 与磁盘空间预先准备。

9.2 案例 1:Qwen3-4B + DSpark 全流程

最完整的 walkthrough,对应论文 Section 4.1 实验设置。

bash 复制代码
# === Step 1: 下载并切分数据 ===
python scripts/data/download_and_split.py \
    --dataset-name mlabonne/open-perfectblend \
    --test-size 0.05 \
    --train-output-path train_datasets/perfectblend_train.jsonl \
    --test-output-dir eval_datasets \
    --skip-existing

# 产物:train_datasets/perfectblend_train.jsonl + eval_datasets/*.jsonl

# === Step 2: 用 sglang 重生成回答 ===
# 2.1 启动 8 个 sglang worker(一个终端)
bash scripts/data/launch_sglang_server.sh
# 默认 8 端口 30000-30007,日志在 logs/sglang_qwen3_4b/

# 2.2 另一个终端跑重生成
python scripts/data/generate_train_data.py \
    --model Qwen/Qwen3-4B \
    --server-address 127.0.0.1:30000 127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 \
                    127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006 127.0.0.1:30007 \
    --concurrency 32 \
    --temperature 0.7 --top-p 0.8 --top-k 20 --min-p 0 \
    --max-tokens 4096 \
    --disable-thinking \
    --resume \
    --input-file-path train_datasets/perfectblend_train.jsonl \
    --output-file-path train_datasets/qwen3_4b/perfectblend_train_regen.jsonl

# 产物:train_datasets/qwen3_4b/perfectblend_train_regen.jsonl
# 失败样本:train_datasets/qwen3_4b/perfectblend_train_regen_error.jsonl

# 2.3 停 sglang 释放 GPU
# Ctrl+C 或 pkill -f sglang

# === Step 3: 生成 target cache(38TB!)===
export CUDA_VISIBLE_DEVICES=${CUDA_VISIBLE_DEVICES:-0,1,2,3,4,5,6,7}
export MASTER_ADDR=${MASTER_ADDR:-127.0.0.1}
export MASTER_PORT=${MASTER_PORT:-29500}
export RANK=${RANK:-0}
export WORLD_SIZE=${WORLD_SIZE:-1}

python scripts/data/prepare_target_cache.py \
    --config config/dspark/dspark_qwen3_4b.py \
    --train-data-path train_datasets/qwen3_4b/perfectblend_train_regen.jsonl \
    --output-dir ${HOME}/.cache/deepspec/qwen3_4b_target_cache \
    --local-batch-size 16

# 产物:~/.cache/deepspec/qwen3_4b_target_cache/(约 38TB)

# === Step 4: 训练 DSpark ===
bash scripts/train/train.sh
# 等价于:
python train.py \
    --config config/dspark/dspark_qwen3_4b.py \
    --opts "data.target_cache_path=${HOME}/.cache/deepspec/qwen3_4b_target_cache"

# 产物:~/checkpoints/deepspec/dspark_block8_qwen3_4b/step_<N>/
#       ~/checkpoints/deepspec/dspark_block8_qwen3_4b/step_latest
#       ~/tensorboard/deepspec/dspark_block8_qwen3_4b/

# === Step 5: 评测 ===
bash scripts/eval/eval.sh
# 等价于:
python eval.py \
    --target_name_or_path Qwen/Qwen3-4B \
    --draft_name_or_path ~/checkpoints/deepspec/dspark_block8_qwen3_4b/step_latest \
    --temperature 1.0 \
    --max-new-tokens 2048

# 产物:stdout 打印 9 benchmark 的 τ

预期产出文件 :参考 08 实验复现 §8.7 的清单。

9.3 案例 2:复用 released checkpoint 直接评测

跳过训练,直接用 DeepSeek 发布的 checkpoint 跑 9 benchmark。

bash 复制代码
# DSpark on Qwen3-4B
python eval.py \
    --target_name_or_path Qwen/Qwen3-4B \
    --draft_name_or_path deepseek-ai/dspark_qwen3_4b_block7 \
    --temperature 1.0

# DSpark on Qwen3-8B
python eval.py \
    --target_name_or_path Qwen/Qwen3-8B \
    --draft_name_or_path deepseek-ai/dspark_qwen3_8b_block7 \
    --temperature 1.0

# DSpark on Gemma4-12B
python eval.py \
    --target_name_or_path google/gemma-4-12b-it \
    --draft_name_or_path deepseek-ai/dspark_gemma4_12b_block7 \
    --temperature 1.0

# Eagle3 对比基线
python eval.py \
    --target_name_or_path Qwen/Qwen3-4B \
    --draft_name_or_path deepseek-ai/eagle3_qwen3_4b_ttt7 \
    --temperature 1.0

# DFlash 对比基线
python eval.py \
    --target_name_or_path Qwen/Qwen3-4B \
    --draft_name_or_path deepseek-ai/dflash_qwen3_4b_block7 \
    --temperature 1.0

released checkpoint 列表见 README.md:55-62(file:///workspace/README.md#L55-62),每行对应论文 Table 1 的一个 cell。

9.4 案例 3:切换到 Gemma4-12B target

Gemma4 与 Qwen3 的差异在 chat template、采样参数、attention 实现。
#mermaid-svg-V1Tm7UR02NykUriD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-V1Tm7UR02NykUriD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-V1Tm7UR02NykUriD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-V1Tm7UR02NykUriD .error-icon{fill:#552222;}#mermaid-svg-V1Tm7UR02NykUriD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-V1Tm7UR02NykUriD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-V1Tm7UR02NykUriD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-V1Tm7UR02NykUriD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-V1Tm7UR02NykUriD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-V1Tm7UR02NykUriD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-V1Tm7UR02NykUriD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-V1Tm7UR02NykUriD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-V1Tm7UR02NykUriD .marker.cross{stroke:#333333;}#mermaid-svg-V1Tm7UR02NykUriD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-V1Tm7UR02NykUriD p{margin:0;}#mermaid-svg-V1Tm7UR02NykUriD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-V1Tm7UR02NykUriD .cluster-label text{fill:#333;}#mermaid-svg-V1Tm7UR02NykUriD .cluster-label span{color:#333;}#mermaid-svg-V1Tm7UR02NykUriD .cluster-label span p{background-color:transparent;}#mermaid-svg-V1Tm7UR02NykUriD .label text,#mermaid-svg-V1Tm7UR02NykUriD span{fill:#333;color:#333;}#mermaid-svg-V1Tm7UR02NykUriD .node rect,#mermaid-svg-V1Tm7UR02NykUriD .node circle,#mermaid-svg-V1Tm7UR02NykUriD .node ellipse,#mermaid-svg-V1Tm7UR02NykUriD .node polygon,#mermaid-svg-V1Tm7UR02NykUriD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-V1Tm7UR02NykUriD .rough-node .label text,#mermaid-svg-V1Tm7UR02NykUriD .node .label text,#mermaid-svg-V1Tm7UR02NykUriD .image-shape .label,#mermaid-svg-V1Tm7UR02NykUriD .icon-shape .label{text-anchor:middle;}#mermaid-svg-V1Tm7UR02NykUriD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-V1Tm7UR02NykUriD .rough-node .label,#mermaid-svg-V1Tm7UR02NykUriD .node .label,#mermaid-svg-V1Tm7UR02NykUriD .image-shape .label,#mermaid-svg-V1Tm7UR02NykUriD .icon-shape .label{text-align:center;}#mermaid-svg-V1Tm7UR02NykUriD .node.clickable{cursor:pointer;}#mermaid-svg-V1Tm7UR02NykUriD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-V1Tm7UR02NykUriD .arrowheadPath{fill:#333333;}#mermaid-svg-V1Tm7UR02NykUriD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-V1Tm7UR02NykUriD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-V1Tm7UR02NykUriD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-V1Tm7UR02NykUriD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-V1Tm7UR02NykUriD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-V1Tm7UR02NykUriD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-V1Tm7UR02NykUriD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-V1Tm7UR02NykUriD .cluster text{fill:#333;}#mermaid-svg-V1Tm7UR02NykUriD .cluster span{color:#333;}#mermaid-svg-V1Tm7UR02NykUriD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-V1Tm7UR02NykUriD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-V1Tm7UR02NykUriD rect.text{fill:none;stroke-width:0;}#mermaid-svg-V1Tm7UR02NykUriD .icon-shape,#mermaid-svg-V1Tm7UR02NykUriD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-V1Tm7UR02NykUriD .icon-shape p,#mermaid-svg-V1Tm7UR02NykUriD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-V1Tm7UR02NykUriD .icon-shape .label rect,#mermaid-svg-V1Tm7UR02NykUriD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-V1Tm7UR02NykUriD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-V1Tm7UR02NykUriD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-V1Tm7UR02NykUriD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Gemma4 vs Qwen3 差异
config: config/dspark/dspark_gemma4_12b.py
chat_template: 'gemma4'
assistant_loss_prefix:

'<|channel>thought

'
attention: global_head_dim

  • attention_k_eq_v
    logits: final_logit_softcapping
    embedding: scaled sqrt H
    sglang 采样参数需查官方推荐

图说明: Gemma4 切换需同时改 6 处。最关键的是 assistant_loss_prefix------Gemma4 非思考模式要求每个 assistant content 前加 <|channel>thought\n<channel|> 前缀,否则 loss_mask 会错位(parser.py:30-51(file:///workspace/deepspec/data/parser.py#L30-51) 的 gemma4 注册项)。

bash 复制代码
# 1. 启动 sglang for Gemma4-12B(采样参数查官方推荐)
bash scripts/data/launch_sglang_server.sh  # 改脚本里的 model 路径

# 2. 重生成回答
python scripts/data/generate_train_data.py \
    --model google/gemma-4-12b-it \
    --server-address 127.0.0.1:30000 127.0.0.1:30001 ... \
    --temperature <查官方推荐> --top-p <...> --top-k <...> \
    --max-tokens 4096 \
    --input-file-path train_datasets/perfectblend_train.jsonl \
    --output-file-path train_datasets/gemma4_12b/perfectblend_train_regen.jsonl

# 3. 生成 target cache(用 Gemma4 config)
python scripts/data/prepare_target_cache.py \
    --config config/dspark/dspark_gemma4_12b.py \
    --train-data-path train_datasets/gemma4_12b/perfectblend_train_regen.jsonl \
    --output-dir ${HOME}/.cache/deepspec/gemma4_12b_target_cache \
    --local-batch-size 16

# 4. 训练
python train.py \
    --config config/dspark/dspark_gemma4_12b.py \
    --opts "data.target_cache_path=${HOME}/.cache/deepspec/gemma4_12b_target_cache"

# 5. 评测
python eval.py \
    --target_name_or_path google/gemma-4-12b-it \
    --draft_name_or_path ~/checkpoints/deepspec/dspark_block8_gemma4_12b/step_latest \
    --temperature 1.0

9.5 案例 4:自定义数据集接入

把自有数据集接入评测:
#mermaid-svg-UScPk0VkViNBey0d{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-UScPk0VkViNBey0d .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-UScPk0VkViNBey0d .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-UScPk0VkViNBey0d .error-icon{fill:#552222;}#mermaid-svg-UScPk0VkViNBey0d .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UScPk0VkViNBey0d .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-UScPk0VkViNBey0d .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UScPk0VkViNBey0d .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UScPk0VkViNBey0d .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-UScPk0VkViNBey0d .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UScPk0VkViNBey0d .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UScPk0VkViNBey0d .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UScPk0VkViNBey0d .marker.cross{stroke:#333333;}#mermaid-svg-UScPk0VkViNBey0d svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UScPk0VkViNBey0d p{margin:0;}#mermaid-svg-UScPk0VkViNBey0d .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-UScPk0VkViNBey0d .cluster-label text{fill:#333;}#mermaid-svg-UScPk0VkViNBey0d .cluster-label span{color:#333;}#mermaid-svg-UScPk0VkViNBey0d .cluster-label span p{background-color:transparent;}#mermaid-svg-UScPk0VkViNBey0d .label text,#mermaid-svg-UScPk0VkViNBey0d span{fill:#333;color:#333;}#mermaid-svg-UScPk0VkViNBey0d .node rect,#mermaid-svg-UScPk0VkViNBey0d .node circle,#mermaid-svg-UScPk0VkViNBey0d .node ellipse,#mermaid-svg-UScPk0VkViNBey0d .node polygon,#mermaid-svg-UScPk0VkViNBey0d .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-UScPk0VkViNBey0d .rough-node .label text,#mermaid-svg-UScPk0VkViNBey0d .node .label text,#mermaid-svg-UScPk0VkViNBey0d .image-shape .label,#mermaid-svg-UScPk0VkViNBey0d .icon-shape .label{text-anchor:middle;}#mermaid-svg-UScPk0VkViNBey0d .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-UScPk0VkViNBey0d .rough-node .label,#mermaid-svg-UScPk0VkViNBey0d .node .label,#mermaid-svg-UScPk0VkViNBey0d .image-shape .label,#mermaid-svg-UScPk0VkViNBey0d .icon-shape .label{text-align:center;}#mermaid-svg-UScPk0VkViNBey0d .node.clickable{cursor:pointer;}#mermaid-svg-UScPk0VkViNBey0d .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-UScPk0VkViNBey0d .arrowheadPath{fill:#333333;}#mermaid-svg-UScPk0VkViNBey0d .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-UScPk0VkViNBey0d .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-UScPk0VkViNBey0d .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UScPk0VkViNBey0d .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-UScPk0VkViNBey0d .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UScPk0VkViNBey0d .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-UScPk0VkViNBey0d .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-UScPk0VkViNBey0d .cluster text{fill:#333;}#mermaid-svg-UScPk0VkViNBey0d .cluster span{color:#333;}#mermaid-svg-UScPk0VkViNBey0d div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-UScPk0VkViNBey0d .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-UScPk0VkViNBey0d rect.text{fill:none;stroke-width:0;}#mermaid-svg-UScPk0VkViNBey0d .icon-shape,#mermaid-svg-UScPk0VkViNBey0d .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UScPk0VkViNBey0d .icon-shape p,#mermaid-svg-UScPk0VkViNBey0d .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-UScPk0VkViNBey0d .icon-shape .label rect,#mermaid-svg-UScPk0VkViNBey0d .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UScPk0VkViNBey0d .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-UScPk0VkViNBey0d .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-UScPk0VkViNBey0d :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 接入步骤
准备 JSONL

每行 {turns: user_msg}
放到 eval_datasets/.jsonl
eval.py 的 TASKS 加

('your_task', N)
eval.py

图说明: 评测数据格式:每行 JSON 含 {"turns": [{"role": "user", "content": "..."}]},只放 user turn(assistant 由 target/draft 生成)。在 eval.py:18-28(file:///workspace/eval.py#L18-28) 的 TASKS 列表加 ("your_task", <样本数>)parser.pyGeneralParser 会用对应 chat_template 渲染。

python 复制代码
# eval.py 修改示例
TASKS = [
    ("gsm8k", 500),
    ...
    ("your_task", 200),  # 新增
]

自定义训练数据类似:JSONL 每行 {"conversations": [{"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]},用 download_and_split.pyROLE_MAPPINGdownload_and_split.py:12-18(file:///workspace/scripts/data/download_and_split.py#L12-18))映射角色。若 role 不在已知列表,会被 validate_conversations 过滤(download_and_split.py:131-141(file:///workspace/scripts/data/download_and_split.py#L131-141))。

9.6 案例 5:调参实验

--opts 覆盖 config 任意字段,无需改代码:

bash 复制代码
# 调 block_size(复现论文 Figure 4 proposal length 扫描)
python train.py --config config/dspark/dspark_qwen3_4b.py \
    --opts "model.block_size=12" \
           "data.target_cache_path=${target_cache_dir}"

# 关闭 Markov head(退化为 DFlash 行为)
python train.py --config config/dspark/dspark_qwen3_4b.py \
    --opts "model.markov_rank=0" \
           "data.target_cache_path=${target_cache_dir}"

# 切换 Markov head 为 RNN(复现论文 Figure 4 RNN 曲线)
python train.py --config config/dspark/dspark_qwen3_4b.py \
    --opts "model.markov_head_type=rnn" \
           "data.target_cache_path=${target_cache_dir}"

# 调 loss 权重
python train.py --config config/dspark/dspark_qwen3_4b.py \
    --opts "model.ce_loss_alpha=0.5" "model.l1_loss_alpha=0.5" \
           "data.target_cache_path=${target_cache_dir}"

# 调训练参数
python train.py --config config/dspark/dspark_qwen3_4b.py \
    --opts "train.lr=3.0e-4" "train.num_train_epochs=5" \
           "data.target_cache_path=${target_cache_dir}"

# 减小 num_draft_layers(复现 Figure 3 depth 扫描)
python train.py --config config/dspark/dspark_qwen3_4b.py \
    --opts "model.num_draft_layers=2" \
           "data.target_cache_path=${target_cache_dir}"

--opts 解析逻辑在 utils/config.py:113-131(file:///workspace/deepspec/utils/config.py#L113-131),值用 yaml 解析(数字/字符串/列表都可)。每个 --opts 一次只覆盖一个字段,多个字段多次传 --opts

9.7 自定义 target 模型接入

#mermaid-svg-hWhlTSQM8E5HkdVw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hWhlTSQM8E5HkdVw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hWhlTSQM8E5HkdVw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hWhlTSQM8E5HkdVw .error-icon{fill:#552222;}#mermaid-svg-hWhlTSQM8E5HkdVw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hWhlTSQM8E5HkdVw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hWhlTSQM8E5HkdVw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hWhlTSQM8E5HkdVw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hWhlTSQM8E5HkdVw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hWhlTSQM8E5HkdVw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hWhlTSQM8E5HkdVw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hWhlTSQM8E5HkdVw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hWhlTSQM8E5HkdVw .marker.cross{stroke:#333333;}#mermaid-svg-hWhlTSQM8E5HkdVw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hWhlTSQM8E5HkdVw p{margin:0;}#mermaid-svg-hWhlTSQM8E5HkdVw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-hWhlTSQM8E5HkdVw .cluster-label text{fill:#333;}#mermaid-svg-hWhlTSQM8E5HkdVw .cluster-label span{color:#333;}#mermaid-svg-hWhlTSQM8E5HkdVw .cluster-label span p{background-color:transparent;}#mermaid-svg-hWhlTSQM8E5HkdVw .label text,#mermaid-svg-hWhlTSQM8E5HkdVw span{fill:#333;color:#333;}#mermaid-svg-hWhlTSQM8E5HkdVw .node rect,#mermaid-svg-hWhlTSQM8E5HkdVw .node circle,#mermaid-svg-hWhlTSQM8E5HkdVw .node ellipse,#mermaid-svg-hWhlTSQM8E5HkdVw .node polygon,#mermaid-svg-hWhlTSQM8E5HkdVw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hWhlTSQM8E5HkdVw .rough-node .label text,#mermaid-svg-hWhlTSQM8E5HkdVw .node .label text,#mermaid-svg-hWhlTSQM8E5HkdVw .image-shape .label,#mermaid-svg-hWhlTSQM8E5HkdVw .icon-shape .label{text-anchor:middle;}#mermaid-svg-hWhlTSQM8E5HkdVw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hWhlTSQM8E5HkdVw .rough-node .label,#mermaid-svg-hWhlTSQM8E5HkdVw .node .label,#mermaid-svg-hWhlTSQM8E5HkdVw .image-shape .label,#mermaid-svg-hWhlTSQM8E5HkdVw .icon-shape .label{text-align:center;}#mermaid-svg-hWhlTSQM8E5HkdVw .node.clickable{cursor:pointer;}#mermaid-svg-hWhlTSQM8E5HkdVw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hWhlTSQM8E5HkdVw .arrowheadPath{fill:#333333;}#mermaid-svg-hWhlTSQM8E5HkdVw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hWhlTSQM8E5HkdVw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hWhlTSQM8E5HkdVw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hWhlTSQM8E5HkdVw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hWhlTSQM8E5HkdVw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hWhlTSQM8E5HkdVw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hWhlTSQM8E5HkdVw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hWhlTSQM8E5HkdVw .cluster text{fill:#333;}#mermaid-svg-hWhlTSQM8E5HkdVw .cluster span{color:#333;}#mermaid-svg-hWhlTSQM8E5HkdVw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hWhlTSQM8E5HkdVw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hWhlTSQM8E5HkdVw rect.text{fill:none;stroke-width:0;}#mermaid-svg-hWhlTSQM8E5HkdVw .icon-shape,#mermaid-svg-hWhlTSQM8E5HkdVw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hWhlTSQM8E5HkdVw .icon-shape p,#mermaid-svg-hWhlTSQM8E5HkdVw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hWhlTSQM8E5HkdVw .icon-shape .label rect,#mermaid-svg-hWhlTSQM8E5HkdVw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hWhlTSQM8E5HkdVw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hWhlTSQM8E5HkdVw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hWhlTSQM8E5HkdVw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 接入新 target 步骤
写 config//_.py

参照 config/dspark/dspark_qwen3_4b.py
确定 target_layer_ids

不能含最后一层
确定 mask_token_id

查 target tokenizer
parser.py TEMPLATE_REGISTRY

注册 chat template 或复用
确定 sglang 采样参数

查 target 推荐
写 modeling///

若 target 不基于 Qwen3/Gemma4
跑数据准备 + 训练 + 评测

图说明: 接入新 target 分两种情况。情况 1 (target 基于 Qwen3/Gemma4,只是 size 不同):只需写新 config 文件,复用现有 modeling 后端,改 target_model_name_or_pathtarget_layer_ids(层数对得上)、mask_token_idchat_template情况 2 (target 是新架构,如 Llama/Mistral):需要在 deepspec/modeling/dspark/<your_backend>/ 写新后端,参照 qwen3/modeling.py(file:///workspace/deepspec/modeling/dspark/qwen3/modeling.py) 实现 Qwen3DSparkModel 等价的 forwardcompute_logits,并加 eval/dspark/evaluator.py 的 evaluator 类与 eval.pyEVALUATORS 注册项。

9.8 故障排查 FAQ

Q1: OOM(显存不足)
复制代码
RuntimeError: CUDA out of memory

A :① 减小 model.num_anchors(如 256);② 减小 model.num_draft_layers;③ 关闭 train.torch_compile;④ 改 train.sharding_strategyfull_shardlocal_batch_size 不要改(已经是 1)。

Q2: target cache 不匹配
复制代码
AssertionError: target_layer_ids mismatch

A :cache 是用某个 config 生成的,训练用另一个 config 时 target_layer_ids 必须一致。检查 ~/.cache/deepspec/<target>_target_cache/manifest.jsontarget_layer_ids 字段,与训练 config 对齐。

Q3: resume 失败
复制代码
AssertionError: saved_world_size != world_size

A :resume 时 topology 必须一致。改 world_size/local_batch_size 不能 resume,需从头训。检查 ~/checkpoints/.../training_state.rank0.ptsaved_world_size

Q4: sglang 连接超时
复制代码
requests.exceptions.ReadTimeout

A :① 检查 sglang server 是否启动(curl http://127.0.0.1:30000/v1/models);② 减小 --concurrency;③ 加 --resume 跳过已完成;④ 检查 --server-address 端口数与 sglang worker 数一致。

Q5: CUDA prefetcher 报错
复制代码
RuntimeError: Cannot re-initialize CUDA in forked subprocess

A :DataLoader 的 num_workers > 0 时,worker 进程不能初始化 CUDA。CUDAPrefetcher 在主进程初始化 stream,worker 只做 CPU 操作。检查 cuda_prefetcher.py:14-73(file:///workspace/deepspec/data/cuda_prefetcher.py#L14-73) 是否被正确包裹。

Q6: eval 时 confidence 校准无输出

A--confidence-threshold 必须设为 0.0 才会启用 ConfidenceHeadRecorderevaluator.py:46-48(file:///workspace/deepspec/eval/dspark/evaluator.py#L46-48))。设了阈值会跳过校准(因采样被截断不再无偏)。

Q7: eval 报 architectures not found
复制代码
KeyError: 'LlamaForCausalLM'

Aeval.pyEVALUATORS 字典只认 DSpark/Eagle3 的 architectures。若 draft 是其它类型,需要:① 在 eval/ 下实现新 evaluator;② 在 eval.py:10-16 注册。

Q8: 训练 loss 不下降

A :① 检查 target_cache_path 是否正确;② 检查 loss_mask 是否覆盖 assistant 部分(用 parser 验证);③ 检查 target_layer_ids 是否在 target 模型层数范围内;④ 检查 lr 是否合适(默认 6.0e-4)。


小结段(总)

DeepSpec 的使用门槛主要在数据准备 (38TB target cache)与config 对齐 (chat template、采样参数、layer_ids)。一旦数据准备完成,训练与评测可快速迭代--------opts 让超参实验零代码改动,released checkpoint 让无训练资源的用户也能复现论文结果。

使用要点回顾:

  1. 环境pip install -r requirements.txt + sglang 单独装 + 8 GPU + 38TB 磁盘。
  2. 数据三步:download_and_split → launch_sglang + generate_train_data → prepare_target_cache。
  3. 训练python train.py --config ... --opts ...,checkpoint 在 ~/checkpoints/
  4. 评测python eval.py --target ... --draft ...,9 benchmark 自动跑。
  5. 自定义:新数据集加 JSONL + 改 TASKS;新 target 写 config(基于 Qwen3/Gemma4 则无需新 modeling)。
  6. 调参--opts "a.b.c=value" 覆盖任意 config 字段,零代码改动。
  7. FAQ:8 类常见问题都有对应代码校验或文档警告。

延伸阅读 :进入 10 总结 看全栈工程经验提炼;进入 08 实验复现 看如何用案例 1-5 复现论文实验。论文 Section 4.1 描述的训练设置在 DSpark_paper.pdf(file:///workspace/DSpark_paper.pdf),README 的 Quick Start(file:///workspace/README.md) 给出最简命令。