Add the Multi-Token Prediction head and a model card

#1
by rkazants - opened
Files changed (3) hide show
  1. README.md +65 -0
  2. config.json +10 -1
  3. model.safetensors +2 -2
README.md CHANGED
@@ -1,3 +1,68 @@
1
  ---
2
  license: apache-2.0
 
 
 
 
 
3
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  license: apache-2.0
3
+ library_name: transformers
4
+ pipeline_tag: image-text-to-text
5
+ tags:
6
+ - tiny-random
7
+ - testing
8
  ---
9
+
10
+ # tiny-random-qwen38-flash-next
11
+
12
+ A tiny model with random weights and the architecture of
13
+ [Qwen3.8-Flash-Next](https://huggingface.co/Qwen/Qwen3.8-Flash-Next) (`qwen4_exp`, `Qwen4ExpForConditionalGeneration`),
14
+ for testing (optimum-intel / OpenVINO). Its outputs are not meaningful. It needs transformers >= 5.17.
15
+
16
+ ## Architecture
17
+
18
+ Every component type of the real model is present, with the same structure and smaller sizes:
19
+
20
+ | Component | Tiny model | Qwen3.8-Flash-Next |
21
+ |---|---|---|
22
+ | Layers | 8 = 2 × (3 Gated DeltaNet + 1 Qwen Sparse Attention) | 48 = 12 × (3 + 1) |
23
+ | Hidden size | 16 | 2560 |
24
+ | Qwen Sparse Attention (QSA) | 4 query / 2 KV heads × 64; indexer 4 heads × 16, blocks of 4 tokens, budget 8 tokens | 24 / 2 × 256; indexer 4 × 128, blocks of 4, budget 2048 |
25
+ | Gated DeltaNet | 2 key / 6 value heads × 8 | 16 / 48 × 128 |
26
+ | MoE | 16 experts, top-4, shared expert | 512 experts, top-10, shared expert |
27
+ | Hyper-connections | 4 streams, low rank 8 | 4 streams, low rank 320 |
28
+ | N-gram PLE (layer 2) | bi- and tri-grams, 2 heads per order, prime vocabularies from 1000, 4 shards | 8 heads per order, prime vocabularies from 2·10^7, 128 shards |
29
+ | Multi-Token Prediction head | 1 QSA layer (`mtp.*`) | 1 QSA layer (`mtp.*`) |
30
+ | Vision encoder | depth 2, hidden 32 | depth 27, hidden 1152 |
31
+ | Vocabulary, tokenizer, chat template, processors | the real ones | |
32
+
33
+ The selection budget is small so that QSA is really sparse on short prompts.
34
+
35
+ The checkpoint keeps the layout of the real one:
36
+ - fused 3D `experts.gate_up_proj` / `experts.down_proj`;
37
+ - the n-gram table split into `ngram_embedding.shard_*`;
38
+ - the MTP head under `mtp.`.
39
+
40
+ transformers does not build the MTP head (`_keys_to_ignore_on_load_unexpected = ["^mtp.*"]`) and ignores its weights
41
+ when loading. Its structure follows vLLM (`vllm/models/qwen4_exp`):
42
+ - `fc_embedding` projects the next token's embedding;
43
+ - a shared `fc_hidden` projects the main model's pre-final-mixer streams;
44
+ - the projected embedding is added to every stream;
45
+ - one QSA decoder layer and the head's `hyper_connection_mixer` follow, then the shared `lm_head`.
46
+
47
+ ## Initialization
48
+
49
+ The default initialization (std 0.02) gives nearly uniform logits. Greedy tokens then depend on rounding noise, and
50
+ comparing runtimes means little. The weights are therefore drawn with more variance:
51
+ - layers: std 0.25;
52
+ - embeddings: std 1;
53
+ - `lm_head`: std 2;
54
+ - MoE routers: std 1.
55
+
56
+ The same scheme is used for the MTP head.
57
+
58
+ The model was checked on text, image and video prompts. For both the main model and the MTP head:
59
+ - outputs are finite, with logits std about 4 and clear greedy top-2 margins (median above 0.3);
60
+ - 32 greedy tokens are all or nearly all distinct, with no repetition runs;
61
+ - all experts are used;
62
+ - QSA drops 23–93% of the visible tokens.
63
+
64
+ For the main model, the n-gram PLE contributes 18–59% of the residual-stream norm.
65
+
66
+ For the MTP head:
67
+ - its predictions depend on both of its inputs;
68
+ - a chained second draft step stays healthy.
config.json CHANGED
@@ -45,7 +45,16 @@
45
  "max_position_embeddings": 262144,
46
  "model_type": "qwen4_exp_text",
47
  "moe_intermediate_size": 16,
48
- "mtp_num_hidden_layers": 0,
 
 
 
 
 
 
 
 
 
49
  "mtp_use_dedicated_embeddings": false,
50
  "ngram_size": 3,
51
  "ngram_vocab_size_base": 1000,
 
45
  "max_position_embeddings": 262144,
46
  "model_type": "qwen4_exp_text",
47
  "moe_intermediate_size": 16,
48
+ "mtp": {
49
+ "hybrid": true,
50
+ "layer_types": [
51
+ "full_attention"
52
+ ],
53
+ "mtp_use_hidden_state_from_layer": null,
54
+ "num_hidden_layers": 1,
55
+ "rope_theta": 10000000
56
+ },
57
+ "mtp_num_hidden_layers": 1,
58
  "mtp_use_dedicated_embeddings": false,
59
  "ngram_size": 3,
60
  "ngram_vocab_size_base": 1000,
model.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:0108c317c660ae4fbbe3caec3fd90e92ee8821881a0868a05a7028fdca8674b9
3
- size 33262920
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:56d05794d740324ed97e1a8d5183d9f8b9bab7f80c61c49396eb42df6b6428b5
3
+ size 33408504