joerowell baranowskiadam commited on
Commit
7094493
·
0 Parent(s):

Laguna S 2.1 initial release

Browse files

Co-authored-by: baranowskiadam <baranowskiadam@users.noreply.huggingface.co>

Files changed (5) hide show
  1. .gitattributes +35 -0
  2. README.md +54 -0
  3. config.json +61 -0
  4. config.py +188 -0
  5. model.safetensors +3 -0
.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ library_name: speculators
3
+ base_model:
4
+ - poolside/Laguna-S-2.1-FP8
5
+ tags:
6
+ - speculative-decoding
7
+ - dflash
8
+ - speculators
9
+ ---
10
+
11
+ <p align="center">
12
+ <img alt="poolside-banner" src="https://poolside.ai/assets/laguna/laguna-s-2-1-banner.svg" width="800px">
13
+ </p>
14
+
15
+ <p align="center">
16
+ <a href="https://openrouter.ai/poolside/laguna-s-2.1"><strong>Use on OpenRouter</strong></a> ·
17
+ <a href="https://vercel.com/ai-gateway/models/laguna-s-2.1"><strong>Use on Vercel AI Gateway</strong></a> ·
18
+ <a href="https://poolside.ai/blog/introducing-laguna-s-2-1"><strong>Release blog post</strong></a>
19
+ </p>
20
+
21
+ <br>
22
+
23
+ # poolside/Laguna-S-2.1-DFlash-FP8
24
+
25
+ DFlash speculator for the FP8 target [poolside/Laguna-S-2.1-FP8](https://huggingface.co/poolside/Laguna-S-2.1-FP8). The
26
+ speculator is a 6-layer Laguna-style draft model (BF16); pair it with the FP8 base for
27
+ lower-latency serving via speculative decoding.
28
+
29
+ Trained: `e0630_rhiemann_baseline` SFT, DFlash Stage-2, 15k steps. Recommended
30
+ serving setting: `num_speculative_tokens=7`.
31
+ DFlash upstream support is in progress (vLLM #46853, SGLang #29446, TRT-LLM #15666). Use
32
+ `poolside/Laguna-S-2.1-FP8` as the target model.
33
+
34
+ ## Benchmarks
35
+
36
+ Measured with TP=2, `temperature=0`, and `num_speculative_tokens=15`.
37
+
38
+ ### Throughput speedup
39
+
40
+ | Concurrency | GSM8K | MATH-500 | HumanEval | MBPP | MT-Bench |
41
+ |---:|---:|---:|---:|---:|---:|
42
+ | 1 | 3.179x | 2.938x | 3.269x | 2.380x | 2.603x |
43
+ | 4 | 2.614x | 2.423x | 2.691x | 1.963x | 2.090x |
44
+ | 8 | 2.666x | 2.410x | 2.803x | 1.962x | 2.230x |
45
+ | 16 | 2.618x | 2.364x | 2.866x | 2.031x | 2.302x |
46
+
47
+ ### Acceptance length
48
+
49
+ | Concurrency | GSM8K | MATH-500 | HumanEval | MBPP | MT-Bench |
50
+ |---:|---:|---:|---:|---:|---:|
51
+ | 1 | 5.748 | 5.197 | 5.889 | 4.247 | 4.663 |
52
+ | 4 | 5.765 | 5.212 | 5.882 | 4.218 | 4.411 |
53
+ | 8 | 5.863 | 5.199 | 6.094 | 4.178 | 4.572 |
54
+ | 16 | 5.787 | 5.161 | 6.144 | 4.291 | 4.600 |
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
+ "sliding_window": 512,
14
+ "vocab_size": 100352,
15
+ "layer_types": [
16
+ "sliding_attention",
17
+ "sliding_attention",
18
+ "sliding_attention",
19
+ "sliding_attention",
20
+ "sliding_attention",
21
+ "sliding_attention"
22
+ ],
23
+ "rope_theta": 500000.0,
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:1ab46259fb266139913530cd6448ff6766e7e4f560ea441f03fa2cf5449df244
3
+ size 2229962896