flashmap 0.0.1__tar.gz → 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. {flashmap-0.0.1 → flashmap-0.1.0}/LICENSE +1 -2
  2. flashmap-0.1.0/PKG-INFO +152 -0
  3. flashmap-0.1.0/README.md +121 -0
  4. flashmap-0.1.0/flashmap/__init__.py +14 -0
  5. flashmap-0.1.0/flashmap/configuration_flashmap.py +105 -0
  6. flashmap-0.1.0/flashmap/modeling_flashmap.py +556 -0
  7. flashmap-0.1.0/flashmap/sglang/__init__.py +78 -0
  8. flashmap-0.1.0/flashmap/sglang/jump_bank.py +203 -0
  9. flashmap-0.1.0/flashmap/sglang/kernels.py +457 -0
  10. flashmap-0.1.0/flashmap/sglang/model.py +1076 -0
  11. flashmap-0.1.0/flashmap/sglang/sampler.py +188 -0
  12. flashmap-0.1.0/flashmap/sglang/tree.py +78 -0
  13. flashmap-0.1.0/flashmap/sglang/tree_worker.py +396 -0
  14. flashmap-0.1.0/flashmap/sglang/verify_attention.py +474 -0
  15. flashmap-0.1.0/flashmap/vllm/__init__.py +268 -0
  16. flashmap-0.1.0/flashmap/vllm/fold.py +128 -0
  17. flashmap-0.1.0/flashmap/vllm/kernels.py +443 -0
  18. flashmap-0.1.0/flashmap/vllm/model.py +881 -0
  19. flashmap-0.1.0/flashmap/vllm/speculator.py +235 -0
  20. flashmap-0.1.0/flashmap.egg-info/PKG-INFO +152 -0
  21. flashmap-0.1.0/flashmap.egg-info/SOURCES.txt +25 -0
  22. flashmap-0.1.0/flashmap.egg-info/entry_points.txt +5 -0
  23. flashmap-0.1.0/flashmap.egg-info/requires.txt +14 -0
  24. flashmap-0.1.0/pyproject.toml +51 -0
  25. flashmap-0.0.1/.editorconfig +0 -21
  26. flashmap-0.0.1/.github/ISSUE_TEMPLATE/bug_report.md +0 -25
  27. flashmap-0.0.1/.github/ISSUE_TEMPLATE/config.yml +0 -10
  28. flashmap-0.0.1/.github/ISSUE_TEMPLATE/feature_request.md +0 -18
  29. flashmap-0.0.1/.github/workflows/docs-build.yml +0 -55
  30. flashmap-0.0.1/.github/workflows/docs.yml +0 -31
  31. flashmap-0.0.1/.github/workflows/installation.yml +0 -31
  32. flashmap-0.0.1/.github/workflows/macos.yml +0 -42
  33. flashmap-0.0.1/.github/workflows/pypi.yml +0 -30
  34. flashmap-0.0.1/.github/workflows/ubuntu.yml +0 -47
  35. flashmap-0.0.1/.github/workflows/windows.yml +0 -34
  36. flashmap-0.0.1/.gitignore +0 -107
  37. flashmap-0.0.1/MANIFEST.in +0 -7
  38. flashmap-0.0.1/PKG-INFO +0 -42
  39. flashmap-0.0.1/README.md +0 -17
  40. flashmap-0.0.1/docs/changelog.md +0 -11
  41. flashmap-0.0.1/docs/common.md +0 -3
  42. flashmap-0.0.1/docs/contributing.md +0 -108
  43. flashmap-0.0.1/docs/examples/intro.ipynb +0 -21
  44. flashmap-0.0.1/docs/faq.md +0 -1
  45. flashmap-0.0.1/docs/flashmap.md +0 -4
  46. flashmap-0.0.1/docs/index.md +0 -16
  47. flashmap-0.0.1/docs/installation.md +0 -21
  48. flashmap-0.0.1/docs/overrides/main.html +0 -11
  49. flashmap-0.0.1/docs/usage.md +0 -7
  50. flashmap-0.0.1/flashmap/__init__.py +0 -5
  51. flashmap-0.0.1/flashmap/common.py +0 -7
  52. flashmap-0.0.1/flashmap/flashmap.py +0 -1
  53. flashmap-0.0.1/flashmap.egg-info/PKG-INFO +0 -42
  54. flashmap-0.0.1/flashmap.egg-info/SOURCES.txt +0 -40
  55. flashmap-0.0.1/flashmap.egg-info/entry_points.txt +0 -2
  56. flashmap-0.0.1/flashmap.egg-info/requires.txt +0 -7
  57. flashmap-0.0.1/mkdocs.yml +0 -86
  58. flashmap-0.0.1/pyproject.toml +0 -82
  59. flashmap-0.0.1/requirements.txt +0 -1
  60. flashmap-0.0.1/requirements_dev.txt +0 -29
  61. flashmap-0.0.1/tests/__init__.py +0 -1
  62. flashmap-0.0.1/tests/test_flashmap.py +0 -21
  63. {flashmap-0.0.1 → flashmap-0.1.0}/flashmap.egg-info/dependency_links.txt +0 -0
  64. {flashmap-0.0.1 → flashmap-0.1.0}/flashmap.egg-info/top_level.txt +0 -0
  65. {flashmap-0.0.1 → flashmap-0.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025, pecwie
3
+ Copyright (c) 2026 Jeff Shen
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
-
@@ -0,0 +1,152 @@
1
+ Metadata-Version: 2.4
2
+ Name: flashmap
3
+ Version: 0.1.0
4
+ Summary: FlashMap: flow map speculative decoding for Hugging Face transformers
5
+ Author: Jeff Shen, Zhejian Zhou, Ryan Lee, Jonathan May, Shirley Ho
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://jshen.net/flashmap
8
+ Project-URL: Repository, https://github.com/al-jshen/flashmap
9
+ Project-URL: Documentation, https://github.com/al-jshen/flashmap#readme
10
+ Project-URL: Model (Qwen3-8B), https://huggingface.co/j-shen/FlashMap-Qwen3-8B
11
+ Project-URL: Model (Qwen3-4B), https://huggingface.co/j-shen/FlashMap-Qwen3-4B
12
+ Keywords: speculative decoding,flow map,draft model,llm inference,transformers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: torch>=2.1
21
+ Requires-Dist: transformers>=4.56
22
+ Provides-Extra: benchmark
23
+ Requires-Dist: datasets; extra == "benchmark"
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest; extra == "test"
26
+ Provides-Extra: sglang
27
+ Requires-Dist: sglang==0.5.20; extra == "sglang"
28
+ Provides-Extra: vllm
29
+ Requires-Dist: vllm<0.32,>=0.31; extra == "vllm"
30
+ Dynamic: license-file
31
+
32
+ # FlashMap: Flow Map Speculative Decoding
33
+
34
+ **[Project page](https://jshen.net/flashmap)** · **Paper** (coming soon) · **[Models](https://huggingface.co/collections/j-shen/flashmap-6ad0feb955bdc30db59769fa)**
35
+
36
+ FlashMap is a drafter for lossless speculative decoding. It proposes a whole block of K tokens in a single pass. Unlike discrete diffusion drafters, which predict each token of the block independently and ignore inter-token dependencies, FlashMap uses a flow map ([Flow Map Language Models](https://arxiv.org/abs/2602.16813)), which jumps from Gaussian noise to the whole block in a single step and can capture dependencies between its tokens. On Qwen3-8B, FlashMap decodes up to 6x faster than the target alone.
37
+
38
+ This repository is a small, standalone implementation for Hugging Face `transformers`. For fast serving, use
39
+ the [SGLang](#serve-with-sglang) or [vLLM](#serve-with-vllm) integration.
40
+
41
+ ## Models
42
+
43
+ | Drafter | Target | Drafter parameters |
44
+ |---|---|---|
45
+ | [j-shen/FlashMap-Qwen3-8B](https://huggingface.co/j-shen/FlashMap-Qwen3-8B) | [Qwen/Qwen3-8B](https://huggingface.co/Qwen/Qwen3-8B) | 500M |
46
+ | [j-shen/FlashMap-Qwen3-4B](https://huggingface.co/j-shen/FlashMap-Qwen3-4B) | [Qwen/Qwen3-4B](https://huggingface.co/Qwen/Qwen3-4B) | 475M |
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ uv venv --python 3.12
52
+ source .venv/bin/activate
53
+ uv pip install flashmap
54
+ ```
55
+
56
+ The package needs only `torch` and `transformers>=4.56`; serving takes the `sglang` or `vllm` extra (below). It
57
+ is tested with torch 2.9 and 2.13 and with transformers 4.57, 5.10, 5.16 and 5.20.
58
+
59
+ ## Quickstart
60
+
61
+ ```python
62
+ import torch
63
+ from transformers import AutoModel, AutoModelForCausalLM, AutoTokenizer
64
+
65
+ tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-8B")
66
+ target = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-8B", dtype=torch.bfloat16).cuda().eval()
67
+ draft = AutoModel.from_pretrained("j-shen/FlashMap-Qwen3-8B", trust_remote_code=True, dtype=torch.bfloat16).cuda().eval()
68
+
69
+ messages = [{"role": "user", "content": "How many positive whole-number divisors does 196 have?"}]
70
+ input_ids = tokenizer.apply_chat_template(
71
+ messages, add_generation_prompt=True, enable_thinking=False, return_tensors="pt", return_dict=True
72
+ )["input_ids"].cuda()
73
+
74
+ output = draft.spec_generate(target, input_ids, max_new_tokens=512, temperature=0.0, num_steps=1)
75
+ print(tokenizer.decode(output.sequences[0, input_ids.shape[1]:], skip_special_tokens=True))
76
+ print(f"acceptance length: {output.acceptance_length:.2f}")
77
+ ```
78
+
79
+ `num_steps=2` drafts with two jumps of the flow map (trading speed for accuracy).
80
+ The model code also ships with the weights, so `AutoModel.from_pretrained(..., trust_remote_code=True)` works without this
81
+ package.
82
+
83
+ ## Serve with SGLang
84
+
85
+ The SGLang integration is a plugin in this package (the `sglang` extra), which SGLang loads automatically.
86
+
87
+ ```bash
88
+ uv venv --python 3.12 .venv-sglang
89
+ source .venv-sglang/bin/activate
90
+ uv pip install "sglang==0.5.20" "flashmap[sglang]"
91
+
92
+ python -m sglang.launch_server --model-path Qwen/Qwen3-8B \
93
+ --speculative-algorithm DSPARK --speculative-draft-model-path j-shen/FlashMap-Qwen3-8B
94
+ ```
95
+
96
+ [Our SpecForge fork](https://github.com/al-jshen/SpecForge/tree/flashmap) trains FlashMap with SGLang's
97
+ training library, and its `specforge export --to hf` writes a trained map as a release folder that
98
+ `flashmap[sglang]` serves as it is.
99
+
100
+ ## Serve with vLLM
101
+
102
+ The vLLM integration is a plugin in this package (the `vllm` extra), which vLLM loads automatically.
103
+
104
+ ```bash
105
+ uv venv --python 3.12 .venv-vllm
106
+ source .venv-vllm/bin/activate
107
+ uv pip install "vllm==0.31.*" "flashmap[vllm]"
108
+
109
+ vllm serve Qwen/Qwen3-8B --speculative-config '{"model": "j-shen/FlashMap-Qwen3-8B", "num_speculative_tokens": 16}'
110
+ ```
111
+
112
+ For sampling at `temperature > 0`, add `"draft_sample_method": "probabilistic"` to the speculative config.
113
+
114
+ Drafters you train yourself ([Training](#training)) are served the same way once converted to the release
115
+ format.
116
+
117
+ ## Sending requests
118
+
119
+ Both servers expose an OpenAI-compatible API, SGLang on port 30000 and vLLM on port 8000.
120
+
121
+ ```python
122
+ from openai import OpenAI
123
+
124
+ client = OpenAI(base_url="http://localhost:30000/v1", api_key="none") # vLLM: port 8000
125
+ response = client.chat.completions.create(
126
+ model=client.models.list().data[0].id,
127
+ messages=[{"role": "user", "content": "How many positive whole-number divisors does 196 have?"}],
128
+ temperature=0,
129
+ extra_body={"chat_template_kwargs": {"enable_thinking": False}},
130
+ )
131
+ print(response.choices[0].message.content)
132
+ ```
133
+
134
+ ## Training
135
+
136
+ FlashMap is trained in two stages: a flow over one-hot token blocks, then a flow map distilled from it. The
137
+ recipes are in the speculators fork
138
+ ([Training FlashMap](https://github.com/al-jshen/speculators/blob/flashmap/docs/user_guide/algorithms/flashmap_training.md))
139
+ and the SpecForge fork ([FlashMap](https://github.com/al-jshen/SpecForge/blob/flashmap/docs/sections/concepts/FlashMap.md)).
140
+ Both write a trained map as a release folder for this package (`speculators convert --algorithm flashmap`,
141
+ `specforge export --to hf`), and [`scripts/convert_checkpoint.py`](https://github.com/al-jshen/flashmap/blob/master/scripts/convert_checkpoint.py) converts
142
+ speculators and SpecForge checkpoints too (`python scripts/convert_checkpoint.py --help`).
143
+
144
+ ## License
145
+
146
+ The code is released under the [MIT license](https://github.com/al-jshen/flashmap/blob/master/LICENSE). The model weights are released under Apache-2.0,
147
+ following Qwen3.
148
+
149
+ FlashMap builds on [DFlash](https://github.com/z-lab/dflash),
150
+ [Flow Map Language Models](https://arxiv.org/abs/2602.16813), [DeepSpec](https://github.com/deepseek-ai/DeepSpec),
151
+ [SGLang](https://github.com/sgl-project/sglang), [vLLM](https://github.com/vllm-project/vllm),
152
+ [speculators](https://github.com/vllm-project/speculators) and [SpecForge](https://github.com/sgl-project/SpecForge).
@@ -0,0 +1,121 @@
1
+ # FlashMap: Flow Map Speculative Decoding
2
+
3
+ **[Project page](https://jshen.net/flashmap)** · **Paper** (coming soon) · **[Models](https://huggingface.co/collections/j-shen/flashmap-6ad0feb955bdc30db59769fa)**
4
+
5
+ FlashMap is a drafter for lossless speculative decoding. It proposes a whole block of K tokens in a single pass. Unlike discrete diffusion drafters, which predict each token of the block independently and ignore inter-token dependencies, FlashMap uses a flow map ([Flow Map Language Models](https://arxiv.org/abs/2602.16813)), which jumps from Gaussian noise to the whole block in a single step and can capture dependencies between its tokens. On Qwen3-8B, FlashMap decodes up to 6x faster than the target alone.
6
+
7
+ This repository is a small, standalone implementation for Hugging Face `transformers`. For fast serving, use
8
+ the [SGLang](#serve-with-sglang) or [vLLM](#serve-with-vllm) integration.
9
+
10
+ ## Models
11
+
12
+ | Drafter | Target | Drafter parameters |
13
+ |---|---|---|
14
+ | [j-shen/FlashMap-Qwen3-8B](https://huggingface.co/j-shen/FlashMap-Qwen3-8B) | [Qwen/Qwen3-8B](https://huggingface.co/Qwen/Qwen3-8B) | 500M |
15
+ | [j-shen/FlashMap-Qwen3-4B](https://huggingface.co/j-shen/FlashMap-Qwen3-4B) | [Qwen/Qwen3-4B](https://huggingface.co/Qwen/Qwen3-4B) | 475M |
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ uv venv --python 3.12
21
+ source .venv/bin/activate
22
+ uv pip install flashmap
23
+ ```
24
+
25
+ The package needs only `torch` and `transformers>=4.56`; serving takes the `sglang` or `vllm` extra (below). It
26
+ is tested with torch 2.9 and 2.13 and with transformers 4.57, 5.10, 5.16 and 5.20.
27
+
28
+ ## Quickstart
29
+
30
+ ```python
31
+ import torch
32
+ from transformers import AutoModel, AutoModelForCausalLM, AutoTokenizer
33
+
34
+ tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen3-8B")
35
+ target = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-8B", dtype=torch.bfloat16).cuda().eval()
36
+ draft = AutoModel.from_pretrained("j-shen/FlashMap-Qwen3-8B", trust_remote_code=True, dtype=torch.bfloat16).cuda().eval()
37
+
38
+ messages = [{"role": "user", "content": "How many positive whole-number divisors does 196 have?"}]
39
+ input_ids = tokenizer.apply_chat_template(
40
+ messages, add_generation_prompt=True, enable_thinking=False, return_tensors="pt", return_dict=True
41
+ )["input_ids"].cuda()
42
+
43
+ output = draft.spec_generate(target, input_ids, max_new_tokens=512, temperature=0.0, num_steps=1)
44
+ print(tokenizer.decode(output.sequences[0, input_ids.shape[1]:], skip_special_tokens=True))
45
+ print(f"acceptance length: {output.acceptance_length:.2f}")
46
+ ```
47
+
48
+ `num_steps=2` drafts with two jumps of the flow map (trading speed for accuracy).
49
+ The model code also ships with the weights, so `AutoModel.from_pretrained(..., trust_remote_code=True)` works without this
50
+ package.
51
+
52
+ ## Serve with SGLang
53
+
54
+ The SGLang integration is a plugin in this package (the `sglang` extra), which SGLang loads automatically.
55
+
56
+ ```bash
57
+ uv venv --python 3.12 .venv-sglang
58
+ source .venv-sglang/bin/activate
59
+ uv pip install "sglang==0.5.20" "flashmap[sglang]"
60
+
61
+ python -m sglang.launch_server --model-path Qwen/Qwen3-8B \
62
+ --speculative-algorithm DSPARK --speculative-draft-model-path j-shen/FlashMap-Qwen3-8B
63
+ ```
64
+
65
+ [Our SpecForge fork](https://github.com/al-jshen/SpecForge/tree/flashmap) trains FlashMap with SGLang's
66
+ training library, and its `specforge export --to hf` writes a trained map as a release folder that
67
+ `flashmap[sglang]` serves as it is.
68
+
69
+ ## Serve with vLLM
70
+
71
+ The vLLM integration is a plugin in this package (the `vllm` extra), which vLLM loads automatically.
72
+
73
+ ```bash
74
+ uv venv --python 3.12 .venv-vllm
75
+ source .venv-vllm/bin/activate
76
+ uv pip install "vllm==0.31.*" "flashmap[vllm]"
77
+
78
+ vllm serve Qwen/Qwen3-8B --speculative-config '{"model": "j-shen/FlashMap-Qwen3-8B", "num_speculative_tokens": 16}'
79
+ ```
80
+
81
+ For sampling at `temperature > 0`, add `"draft_sample_method": "probabilistic"` to the speculative config.
82
+
83
+ Drafters you train yourself ([Training](#training)) are served the same way once converted to the release
84
+ format.
85
+
86
+ ## Sending requests
87
+
88
+ Both servers expose an OpenAI-compatible API, SGLang on port 30000 and vLLM on port 8000.
89
+
90
+ ```python
91
+ from openai import OpenAI
92
+
93
+ client = OpenAI(base_url="http://localhost:30000/v1", api_key="none") # vLLM: port 8000
94
+ response = client.chat.completions.create(
95
+ model=client.models.list().data[0].id,
96
+ messages=[{"role": "user", "content": "How many positive whole-number divisors does 196 have?"}],
97
+ temperature=0,
98
+ extra_body={"chat_template_kwargs": {"enable_thinking": False}},
99
+ )
100
+ print(response.choices[0].message.content)
101
+ ```
102
+
103
+ ## Training
104
+
105
+ FlashMap is trained in two stages: a flow over one-hot token blocks, then a flow map distilled from it. The
106
+ recipes are in the speculators fork
107
+ ([Training FlashMap](https://github.com/al-jshen/speculators/blob/flashmap/docs/user_guide/algorithms/flashmap_training.md))
108
+ and the SpecForge fork ([FlashMap](https://github.com/al-jshen/SpecForge/blob/flashmap/docs/sections/concepts/FlashMap.md)).
109
+ Both write a trained map as a release folder for this package (`speculators convert --algorithm flashmap`,
110
+ `specforge export --to hf`), and [`scripts/convert_checkpoint.py`](https://github.com/al-jshen/flashmap/blob/master/scripts/convert_checkpoint.py) converts
111
+ speculators and SpecForge checkpoints too (`python scripts/convert_checkpoint.py --help`).
112
+
113
+ ## License
114
+
115
+ The code is released under the [MIT license](https://github.com/al-jshen/flashmap/blob/master/LICENSE). The model weights are released under Apache-2.0,
116
+ following Qwen3.
117
+
118
+ FlashMap builds on [DFlash](https://github.com/z-lab/dflash),
119
+ [Flow Map Language Models](https://arxiv.org/abs/2602.16813), [DeepSpec](https://github.com/deepseek-ai/DeepSpec),
120
+ [SGLang](https://github.com/sgl-project/sglang), [vLLM](https://github.com/vllm-project/vllm),
121
+ [speculators](https://github.com/vllm-project/speculators) and [SpecForge](https://github.com/sgl-project/SpecForge).
@@ -0,0 +1,14 @@
1
+ from transformers import AutoConfig, AutoModel
2
+
3
+ from .configuration_flashmap import FlashMapConfig
4
+ from .modeling_flashmap import FlashMapCache, FlashMapDraftModel, FlashMapGenerateOutput
5
+
6
+ # With the package imported, AutoModel loads FlashMap folders without trust_remote_code,
7
+ # and save_pretrained writes the model code next to the weights, so that the folder
8
+ # loads with trust_remote_code=True alone.
9
+ AutoConfig.register(FlashMapConfig.model_type, FlashMapConfig, exist_ok=True)
10
+ AutoModel.register(FlashMapConfig, FlashMapDraftModel, exist_ok=True)
11
+ FlashMapConfig.register_for_auto_class()
12
+ FlashMapDraftModel.register_for_auto_class("AutoModel")
13
+
14
+ __all__ = ["FlashMapCache", "FlashMapConfig", "FlashMapDraftModel", "FlashMapGenerateOutput"]
@@ -0,0 +1,105 @@
1
+ """Configuration of a FlashMap draft model."""
2
+
3
+ from transformers import PretrainedConfig
4
+
5
+
6
+ # Jump grids of the "decoding_error" time schedule (Flow Map Language Models,
7
+ # eq. 25) at the Qwen3 vocabulary size, with the endpoints set to exactly 0 and 1.
8
+ # A draft with ``n`` steps jumps from grid[i] to grid[i + 1] for i < n.
9
+ DEFAULT_JUMP_GRIDS = {
10
+ "1": [0.0, 1.0],
11
+ "2": [0.0, 0.8172569274902344, 1.0],
12
+ "3": [0.0, 0.8010796308517456, 0.8310279846191406, 1.0],
13
+ "4": [0.0, 0.7906050682067871, 0.8172569274902344, 0.8379518389701843, 1.0],
14
+ }
15
+
16
+
17
+ class FlashMapConfig(PretrainedConfig):
18
+ r"""A FlashMap drafter for speculative decoding.
19
+
20
+ FlashMap drafts a block of ``block_size`` tokens after the last verified one
21
+ (the anchor) with a flow map: a DiT that jumps from Gaussian noise over the
22
+ target's vocabulary to the block's per-slot token distributions, conditioned on
23
+ the target model's hidden states through cross-attention.
24
+
25
+ The drafter borrows the target's token embedding and lm_head, which are not part
26
+ of its weights.
27
+
28
+ Args:
29
+ target_model (`str`): Hub id of the target model the drafter was trained for.
30
+ target_hidden_size (`int`): Hidden size of the target model.
31
+ vocab_size (`int`): Vocabulary size of the target model.
32
+ target_layer_ids (`list[int]`): Target decoder layers whose outputs (that is,
33
+ `hidden_states[i + 1]` of a transformers forward) are the drafter's context.
34
+ block_size (`int`): Number of draft tokens per block.
35
+ hidden_size (`int`): Width of the DiT.
36
+ num_hidden_layers (`int`): Number of DiT blocks.
37
+ num_attention_heads (`int`): Attention heads of the DiT.
38
+ intermediate_size (`int`): MLP width of the DiT.
39
+ cond_dim (`int`): Width of the time conditioning.
40
+ time_embed_dim (`int`): Size of the sinusoidal time features.
41
+ time_scale (`float`): Times in [0, 1] are multiplied by this before their
42
+ sinusoidal embedding.
43
+ rope_theta (`float`): RoPE base. RoPE rotates interleaved pairs of channels.
44
+ rms_norm_eps (`float`): Epsilon of the context, anchor and state RMSNorms.
45
+ qk_norm_eps (`float`): Epsilon of the query/key RMSNorms.
46
+ layer_norm_eps (`float`): Epsilon of the adaptive LayerNorms.
47
+ noise_gate (`str`): How the noise term of the state embedding is weighted:
48
+ "jump" by `noise_gate * (t - s)` for a jump from `s` to `t`, "constant" by
49
+ `noise_gate` alone.
50
+ time_schedule (`str`): The schedule the jump grids come from.
51
+ num_steps (`int`): Default number of jumps per draft.
52
+ jump_grids (`dict[str, list[float]]`): Jump times for each number of steps.
53
+ """
54
+
55
+ model_type = "flashmap"
56
+
57
+ def __init__(
58
+ self,
59
+ target_model: str = "Qwen/Qwen3-8B",
60
+ target_hidden_size: int = 4096,
61
+ vocab_size: int = 151936,
62
+ target_layer_ids=(1, 9, 17, 25, 33),
63
+ block_size: int = 16,
64
+ hidden_size: int = 2048,
65
+ num_hidden_layers: int = 6,
66
+ num_attention_heads: int = 16,
67
+ intermediate_size: int = 8192,
68
+ cond_dim: int = 256,
69
+ time_embed_dim: int = 256,
70
+ time_scale: float = 1000.0,
71
+ rope_theta: float = 10000.0,
72
+ rms_norm_eps: float = 1e-6,
73
+ qk_norm_eps: float = 1e-5,
74
+ layer_norm_eps: float = 1e-6,
75
+ noise_gate: str = "jump",
76
+ time_schedule: str = "decoding_error",
77
+ num_steps: int = 1,
78
+ jump_grids=None,
79
+ **kwargs,
80
+ ):
81
+ self.target_model = target_model
82
+ self.target_hidden_size = target_hidden_size
83
+ self.vocab_size = vocab_size
84
+ self.target_layer_ids = list(target_layer_ids)
85
+ self.block_size = block_size
86
+ self.hidden_size = hidden_size
87
+ self.num_hidden_layers = num_hidden_layers
88
+ self.num_attention_heads = num_attention_heads
89
+ self.intermediate_size = intermediate_size
90
+ self.cond_dim = cond_dim
91
+ self.time_embed_dim = time_embed_dim
92
+ self.time_scale = time_scale
93
+ self.rope_theta = rope_theta
94
+ self.rms_norm_eps = rms_norm_eps
95
+ self.qk_norm_eps = qk_norm_eps
96
+ self.layer_norm_eps = layer_norm_eps
97
+ self.noise_gate = noise_gate
98
+ self.time_schedule = time_schedule
99
+ self.num_steps = num_steps
100
+ self.jump_grids = dict(DEFAULT_JUMP_GRIDS if jump_grids is None else jump_grids)
101
+ kwargs.setdefault("tie_word_embeddings", False)
102
+ super().__init__(**kwargs)
103
+
104
+
105
+ __all__ = ["FlashMapConfig"]