Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e7ba6c0
[DataFlow runtime] Phase B1 — TargetEngine ABC + de-EAGLE3 the target…
maocheng23 Jul 1, 2026
20f5f65
[DataFlow runtime] Phase B2 — decouple the target engine from the sgl…
maocheng23 Jul 1, 2026
98b753d
[DataFlow runtime] E0 — layout consolidation: runtime/ is substrate-o…
maocheng23 Jul 4, 2026
83e3eac
[SpecForge] E — draft-architecture registry (@register_draft)
maocheng23 Jul 1, 2026
d7985a7
style: fix draft registry import ordering
maocheng23 Jul 4, 2026
16e7cfe
[SpecForge] Phase E — typed Pydantic config + specforge CLI
maocheng23 Jul 4, 2026
fd2fffa
fix(sglang): make the DataFlow capture backend work on sglang 0.5.14
maocheng23 Jul 5, 2026
08bd2fe
fix(sglang): port parallel-state init in patch.py to sglang 0.5.14
maocheng23 Jul 5, 2026
70e241a
support domino disaggregated training[bug]
jiapingW Jul 7, 2026
e3c7acb
fix bugs
jiapingW Jul 7, 2026
3063d4a
1. dflash family draft model abstract
Jul 9, 2026
62cb3f1
fix lint
Jul 9, 2026
12c27d3
[DataFlow runtime] Domino disagg: 1-server + DP=7 launcher + working …
maocheng23 Jul 7, 2026
832263f
support dspark training
jiapingW Jul 9, 2026
b057d18
support train multi epochs
jiapingW Jul 9, 2026
ea7d529
disagg logging: DP-average loss/acc + log train/accuracy & train/lr
maocheng23 Jul 9, 2026
372b857
examples: dflash 1-server + DP=7 disagg launcher (auto LR-schedule st…
maocheng23 Jul 9, 2026
83ec0c3
examples: add two-node DFlash launcher
maocheng23 Jul 9, 2026
8b2ce67
refactor domino and dspark code
jiapingW Jul 10, 2026
fe0ad18
fix some bugs
jiapingW Jul 10, 2026
02bf0a7
fix lint and grad norm clip bugs[PR663]
jiapingW Jul 10, 2026
69e18e6
feat(data): add validated Qwen ShareGPT regeneration pipelines
jianuo-huang Jul 12, 2026
4f17f85
feat(data): explode multi-turn reasoning into generation events
jianuo-huang Jul 12, 2026
2963b5e
test(domino): add generic overfit and DFLASH serving gates
jianuo-huang Jul 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions bench_domino_mfu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
"""Isolated single-GPU MFU / FLOPs / memory benchmark for the domino trainer.

Removes the data-supply path and DP comm so we measure ONLY the per-step trainer
compute: build the real draft (configs/qwen3-8b-domino.json shapes) with random
weights on one GPU, feed a realistic batch, time fwd+bwd with CUDA events, count
forward FLOPs with torch's FlopCounterMode, and read peak allocated memory.

Reports achieved TFLOP/s and MFU vs H200 bf16 dense peak (989.5 TFLOP/s) for a
sweep of batch sizes, plus per-sample compute (to show it is ~flat in batch =
compute-latency bound, not FLOPs/memory bound).
"""

import json

import torch
import torch.nn as nn
from torch.utils.flop_counter import FlopCounterMode
from transformers import Qwen3Config

from specforge.core.dflash import OnlineDominoModel
from specforge.modeling.draft.dflash import DFlashDraftModel

H200_BF16_TFLOPS = 989.5 # SXM, dense
SEQ = 768
NUM_ANCHORS = 256
CFG_PATH = "configs/qwen3-8b-domino.json"


def build(dtype, device):
raw = json.load(open(CFG_PATH))
dfc = raw["dflash_config"]
cfg = Qwen3Config(
hidden_size=raw["hidden_size"],
num_hidden_layers=raw["num_hidden_layers"],
num_attention_heads=raw["num_attention_heads"],
num_key_value_heads=raw.get("num_key_value_heads", 8),
head_dim=raw.get("head_dim", 128),
intermediate_size=raw["intermediate_size"],
vocab_size=raw["vocab_size"],
max_position_embeddings=raw.get("max_position_embeddings", 40960),
rms_norm_eps=raw.get("rms_norm_eps", 1e-6),
attention_bias=raw.get("attention_bias", False),
attention_dropout=0.0,
rope_theta=raw.get("rope_theta", 1000000.0),
)
cfg._attn_implementation = "sdpa"
cfg.layer_types = ["full_attention"] * raw["num_hidden_layers"]
cfg.num_target_layers = 36
cfg.block_size = raw["block_size"]
cfg.dflash_config = dfc

draft = DFlashDraftModel(cfg).to(device=device, dtype=dtype)
V, H = raw["vocab_size"], raw["hidden_size"]
lm_head = nn.Linear(H, V, bias=False).to(device=device, dtype=dtype)
embed = nn.Embedding(V, H).to(device=device, dtype=dtype)
for p in list(lm_head.parameters()) + list(embed.parameters()):
p.requires_grad_(False)

model = OnlineDominoModel(
draft_model=draft,
target_lm_head=lm_head,
target_embed_tokens=embed,
mask_token_id=dfc["mask_token_id"],
block_size=raw["block_size"],
attention_backend="sdpa",
num_anchors=NUM_ANCHORS,
loss_decay_gamma=7.0,
shift_label=dfc.get("shift_label", True),
)
n_train = sum(p.numel() for p in draft.parameters() if p.requires_grad)
return model, cfg, n_train


def make_inputs(cfg, bsz, dtype, device):
naux = len(cfg.dflash_config["target_layer_ids"])
g = torch.Generator(device="cpu").manual_seed(0)
input_ids = torch.randint(0, cfg.vocab_size, (bsz, SEQ), generator=g).to(device)
hidden = torch.randn(
bsz, SEQ, naux * cfg.hidden_size, generator=g, dtype=torch.float32
).to(device=device, dtype=dtype)
loss_mask = torch.ones(bsz, SEQ, device=device)
return input_ids, hidden, loss_mask


def bench(bsz, dtype=torch.bfloat16, device="cuda", iters=10, warmup=3):
model, cfg, n_train = build(dtype, device)
inp = make_inputs(cfg, bsz, dtype, device)

def step():
for p in model.draft_model.parameters():
p.grad = None
loss, _, _ = model(*inp, lambda_base=0.5)
loss.backward()
return loss

for _ in range(warmup):
step()
torch.cuda.synchronize()

# forward FLOPs (counts mm/bmm/sdpa; flex_attention may be undercounted)
with torch.no_grad():
fc = FlopCounterMode(display=False)
with fc:
model(*inp, lambda_base=0.5)
fwd_flop = fc.get_total_flops()

torch.cuda.reset_peak_memory_stats()
start = torch.cuda.Event(enable_timing=True)
end = torch.cuda.Event(enable_timing=True)
torch.cuda.synchronize()
start.record()
for _ in range(iters):
step()
end.record()
torch.cuda.synchronize()
ms = start.elapsed_time(end) / iters
peak_gb = torch.cuda.max_memory_allocated() / 1e9

# total training FLOP ~ 3x forward (1 fwd + 2 bwd), the standard rule
total_flop = 3.0 * fwd_flop
tflops = total_flop / (ms / 1e3) / 1e12
mfu = 100.0 * tflops / H200_BF16_TFLOPS
per_sample_ms = ms / bsz
print(
f"[bsz={bsz}] step={ms:7.1f}ms per_sample={per_sample_ms:6.1f}ms "
f"fwdFLOP={fwd_flop/1e12:6.2f}T ~totFLOP={total_flop/1e12:6.2f}T "
f"achieved={tflops:6.1f}TFLOP/s MFU={mfu:4.1f}% peakmem={peak_gb:6.1f}GB "
f"draft_params={n_train/1e9:.2f}B",
flush=True,
)
del model
torch.cuda.empty_cache()


if __name__ == "__main__":
print(
f"device={torch.cuda.get_device_name(0)} peak_ref={H200_BF16_TFLOPS} TFLOP/s bf16 dense"
)
for b in (2, 4, 8):
try:
bench(b)
except RuntimeError as e:
print(f"[bsz={b}] FAILED: {str(e)[:120]}")
torch.cuda.empty_cache()
51 changes: 51 additions & 0 deletions configs/qwen3-4b-dspark.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"architectures": [
"DSparkDraftModel"
],
"attention_bias": false,
"attention_dropout": 0.0,
"auto_map": {
"AutoModel": "dspark.DSparkDraftModel"
},
"block_size": 7,
"bos_token_id": 151643,
"dflash_config": {
"mask_token_id": 151669,
"target_layer_ids": [1, 9, 17, 25, 33],
"projector_type": "dspark",
"markov_rank": 256,
"markov_head_type": "vanilla",
"confidence_head_alpha": 1.0,
"enable_confidence_head": true,
"confidence_head_with_markov": true
},
"dtype": "bfloat16",
"eos_token_id": 151645,
"head_dim": 128,
"hidden_act": "silu",
"hidden_size": 2560,
"initializer_range": 0.02,
"intermediate_size": 9728,
"layer_types": [
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention"
],
"max_position_embeddings": 40960,
"max_window_layers": 5,
"model_type": "qwen3",
"num_attention_heads": 32,
"num_hidden_layers": 5,
"num_key_value_heads": 8,
"num_target_layers": 36,
"rms_norm_eps": 1e-06,
"rope_scaling": null,
"rope_theta": 1000000,
"sliding_window": null,
"tie_word_embeddings": false,
"use_cache": true,
"use_sliding_window": false,
"vocab_size": 151936
}
5 changes: 3 additions & 2 deletions configs/qwen3-8b-domino.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"emb_dim": 256,
"architectures": [
"DFlashDraftModel"
"DominoDraftModel"
],
"attention_bias": false,
"attention_dropout": 0.0,
"auto_map": {
"AutoModel": "dflash.DFlashDraftModel"
"AutoModel": "domino.DominoDraftModel"
},
"block_size": 16,
"bos_token_id": 151643,
Expand Down
4 changes: 2 additions & 2 deletions configs/qwen3.5-4b-domino.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"architectures": [
"DFlashDraftModel"
"DominoDraftModel"
],
"attention_bias": false,
"attention_dropout": 0.0,
"auto_map": {
"AutoModel": "dflash.DFlashDraftModel"
"AutoModel": "domino.DominoDraftModel"
},
"block_size": 16,
"bos_token_id": 248043,
Expand Down
52 changes: 52 additions & 0 deletions configs/qwen3.6-27b-domino-full-attention.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"architectures": [
"DFlashDraftModel"
],
"attention_bias": false,
"attention_dropout": 0.0,
"auto_map": {
"AutoModel": "dflash.DFlashDraftModel"
},
"block_size": 16,
"bos_token_id": null,
"dflash_config": {
"mask_token_id": 248070,
"target_layer_ids": [1, 16, 31, 46, 61],
"projector_type": "domino",
"pure_draft_prefix_len": 1,
"emb_dim": 256,
"gru_hidden_dim": 1024,
"shift_label": false
},
"dtype": "bfloat16",
"eos_token_id": 248044,
"head_dim": 128,
"hidden_act": "silu",
"hidden_size": 5120,
"initializer_range": 0.02,
"intermediate_size": 17408,
"layer_types": [
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention"
],
"max_position_embeddings": 262144,
"max_window_layers": 5,
"model_type": "qwen3",
"num_attention_heads": 32,
"num_hidden_layers": 5,
"num_key_value_heads": 8,
"num_target_layers": 64,
"pad_token_id": 248044,
"rms_norm_eps": 1e-06,
"rope_scaling": null,
"rope_theta": 10000000,
"sliding_window": null,
"tie_word_embeddings": false,
"transformers_version": "5.5.3",
"use_cache": true,
"use_sliding_window": false,
"vocab_size": 248320
}
Loading
Loading