joerowell commited on
Commit
5780d51
·
verified ·
1 Parent(s): 4fec8bc

DFlash speculator (polishing, bf16) from DFlash_Stage2/25000

Browse files
Files changed (4) hide show
  1. README.md +13 -0
  2. config.json +61 -0
  3. config.py +188 -0
  4. model.safetensors +3 -0
README.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: other
3
+ tags: [dflash, speculative-decoding, laguna]
4
+ ---
5
+
6
+ # Laguna-S-2.1-DFlash-polishing
7
+
8
+ DFlash speculator (drafter) for Laguna-S-2.1, bf16.
9
+
10
+ - Architecture: `DFlashLagunaForCausalLM` (6 sliding-attention layers, block_size 16).
11
+ - Shares token embedding + lm_head with the target; `draft_vocab_size == vocab_size` (no d2t/t2d).
12
+ - Source checkpoint: `s3://poolside.titan.checkpoints.us-east-2/adam/checkpoints/ft_sft_e0630_rhiemann_baseline_titan_sft_training/0008400/DFlash_Stage2/25000`
13
+ - Loads under vLLM (native `laguna_dflash`) and TRT-LLM (pytorch DFlash backend) as the draft model in a speculative config.
config.json ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "attention_bias": false,
3
+ "head_dim": 128,
4
+ "hidden_act": "silu",
5
+ "hidden_size": 3072,
6
+ "intermediate_size": 12288,
7
+ "max_position_embeddings": 262144,
8
+ "model_type": "laguna",
9
+ "num_attention_heads": 72,
10
+ "num_hidden_layers": 6,
11
+ "num_key_value_heads": 8,
12
+ "rms_norm_eps": 1e-06,
13
+ "rope_theta": 500000.0,
14
+ "sliding_window": 512,
15
+ "vocab_size": 100352,
16
+ "layer_types": [
17
+ "sliding_attention",
18
+ "sliding_attention",
19
+ "sliding_attention",
20
+ "sliding_attention",
21
+ "sliding_attention",
22
+ "sliding_attention"
23
+ ],
24
+ "gating": "per-head",
25
+ "architectures": [
26
+ "DFlashLagunaForCausalLM"
27
+ ],
28
+ "num_experts": 0,
29
+ "sliding_windows": [
30
+ 512,
31
+ 512,
32
+ 512,
33
+ 512,
34
+ 512,
35
+ 512
36
+ ],
37
+ "draft_vocab_size": 100352,
38
+ "torch_dtype": "bfloat16",
39
+ "eagle_aux_hidden_state_layer_ids": [
40
+ 2,
41
+ 11,
42
+ 20,
43
+ 30,
44
+ 39,
45
+ 48
46
+ ],
47
+ "dflash_config": {
48
+ "block_size": 16,
49
+ "mask_token_id": 12,
50
+ "num_target_layers": 48,
51
+ "target_layer_ids": [
52
+ 1,
53
+ 10,
54
+ 19,
55
+ 29,
56
+ 38,
57
+ 47
58
+ ],
59
+ "causal": true
60
+ }
61
+ }
config.py ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Literal
2
+
3
+ from pydantic import Field, field_serializer, field_validator
4
+ from transformers import AutoConfig, PretrainedConfig
5
+ from transformers.models.qwen3.modeling_qwen3 import (
6
+ Qwen3Config,
7
+ )
8
+
9
+ from speculators import SpeculatorModelConfig
10
+
11
+ __all__ = [
12
+ "DFlashSpeculatorConfig",
13
+ ]
14
+
15
+
16
+ @SpeculatorModelConfig.register("dflash")
17
+ class DFlashSpeculatorConfig(SpeculatorModelConfig):
18
+ """
19
+ Configuration for DFlash speculator with vocabulary mapping.
20
+
21
+ DFlash features vocabulary mapping between draft (64K) and target (128K)
22
+ vocabularies, enabling cross-tokenizer speculation.
23
+
24
+ :param transformer_layer_config: Configuration for the transformer decoder layer
25
+ :param draft_vocab_size: Size of draft model vocabulary for speculation
26
+ """
27
+
28
+ speculators_model_type: Literal["dflash"] = "dflash"
29
+ architectures: list[str] = Field(
30
+ default_factory=lambda: ["DFlashSpeculator"],
31
+ description="Model architectures that can load these weights",
32
+ )
33
+
34
+ transformer_layer_config: PretrainedConfig = Field(
35
+ default_factory=Qwen3Config,
36
+ description="Configuration for the transformer decoder layer",
37
+ )
38
+
39
+ draft_vocab_size: int = Field(
40
+ default=32000,
41
+ description="Size of draft model vocabulary for speculation",
42
+ )
43
+
44
+ block_size: int = Field(
45
+ default=8,
46
+ description=(
47
+ "Default size of the draft block predicted with a forward pass of the model"
48
+ ),
49
+ )
50
+
51
+ max_anchors: int = Field(
52
+ default=256,
53
+ description=(
54
+ "Maximum number of anchor positions to sample during training "
55
+ "(controls memory usage and training efficiency)"
56
+ ),
57
+ )
58
+
59
+ target_hidden_size: int | None = Field(
60
+ default=None,
61
+ description="Hidden size of the target model (if different from draft model)",
62
+ )
63
+
64
+ aux_hidden_state_layer_ids: list[int] | None = Field(
65
+ default=None,
66
+ description="Layer IDs of the DFlash auxiliary hidden state layers",
67
+ )
68
+
69
+ decoder_layer_type: Literal["qwen3", "laguna_xs"] = Field(
70
+ default="qwen3",
71
+ description="Decoder layer implementation used by the DFlash drafter.",
72
+ )
73
+
74
+ mask_token_id: int | None = Field(
75
+ default=None,
76
+ description="Token ID used for masking",
77
+ )
78
+
79
+ sliding_window_non_causal: bool = Field(
80
+ default=False,
81
+ description="Use non-causal synthetic block attention for sliding-window layers.",
82
+ )
83
+
84
+ sliding_window_base: Literal["fixed_anchor", "moving_query"] = Field(
85
+ default="moving_query",
86
+ description=(
87
+ "Base-token sliding-window lower-bound policy. 'moving_query' matches "
88
+ "FlashAttention-style SWA during inference; 'fixed_anchor' preserves "
89
+ "the legacy DFlash training mask."
90
+ ),
91
+ )
92
+
93
+ loss_type: Literal["distill", "dflash", "lk", "tv"] = Field(
94
+ default="distill",
95
+ description="DFlash objective. 'lk' uses hard-label LK loss.",
96
+ )
97
+
98
+ ce_weight: float | None = Field(
99
+ default=None,
100
+ description="Additive weight for hard-label DFlash CE.",
101
+ )
102
+
103
+ tv_weight: float | None = Field(
104
+ default=None,
105
+ description="Additive weight for full-distribution TV loss.",
106
+ )
107
+
108
+ kl_weight: float | None = Field(
109
+ default=None,
110
+ description="Additive weight for full-distribution KL distillation.",
111
+ )
112
+
113
+ lk_lambda: float = Field(
114
+ default=0.5,
115
+ description="Blend coefficient for hard-label LK loss.",
116
+ )
117
+
118
+ tv_temperature: float = Field(
119
+ default=1.0,
120
+ description="Teacher softmax temperature for TV/KL terms.",
121
+ )
122
+
123
+ cumacc_weight: bool = Field(
124
+ default=False,
125
+ description="Weight hard-label DFlash CE by draft cumulative acceptance.",
126
+ )
127
+
128
+ veri_cum_acc: bool = Field(
129
+ default=False,
130
+ description="Weight DFlash loss by verifier cumulative acceptance.",
131
+ )
132
+
133
+ veri_acc_temperature: float = Field(
134
+ default=1.0,
135
+ description="Temperature for verifier cumulative acceptance weighting.",
136
+ )
137
+
138
+ static_decay_weight: bool = Field(
139
+ default=True,
140
+ description="Apply DFlash position decay to hard-label CE.",
141
+ )
142
+
143
+ kl_distill_weight: float = Field(
144
+ default=0.0,
145
+ description="Back-compatible alias for kl_weight when kl_weight is unset.",
146
+ )
147
+
148
+ compile_decoder_layers: bool = Field(
149
+ default=True,
150
+ description=(
151
+ "If True, torch.compile each decoder layer forward during training. "
152
+ "The DFlash loss remains eager."
153
+ ),
154
+ )
155
+
156
+ @field_serializer("transformer_layer_config")
157
+ def serialize_transformer_config(self, value: PretrainedConfig) -> dict:
158
+ """Serialize transformer config to dict."""
159
+ return value.to_diff_dict()
160
+
161
+ @field_validator("transformer_layer_config", mode="before")
162
+ @classmethod
163
+ def validate_transformer_config(cls, value: Any) -> PretrainedConfig:
164
+ """Validate and convert transformer config."""
165
+ if isinstance(value, dict):
166
+ config_class: type[PretrainedConfig] = Qwen3Config
167
+ if "model_type" in value:
168
+ config_class = AutoConfig.for_model(
169
+ model_type=value["model_type"]
170
+ ).__class__
171
+ return config_class(**value)
172
+ return value
173
+
174
+ @property
175
+ def target_vocab_size(self) -> int:
176
+ """Get target vocabulary size from transformer config."""
177
+ return self.transformer_layer_config.vocab_size
178
+
179
+ def resolve_loss_weights(self) -> tuple[float, float, float]:
180
+ if self.loss_type == "tv":
181
+ ce_default, tv_default = 0.0, 1.0
182
+ else:
183
+ ce_default, tv_default = 1.0, 0.0
184
+
185
+ ce = ce_default if self.ce_weight is None else self.ce_weight
186
+ tv = tv_default if self.tv_weight is None else self.tv_weight
187
+ kl = self.kl_distill_weight if self.kl_weight is None else self.kl_weight
188
+ return float(ce), float(tv), float(kl)
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:85c6f3f097358226136f366f4a91c90bd662d544745f1f4944e09668db8fbbe7
3
+ size 2229962896