pirola commited on
Commit
1488abb
·
verified ·
1 Parent(s): 3c0a28a

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* 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
 
 
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
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Devstral-24B-NVFP4-NVembed
2
+
3
+ NVFP4-quantized [Devstral-Small-2-24B-Instruct](https://huggingface.co/mistralai/Devstral-Small-2-24B-Instruct) — a 24B-parameter dense coding model that fits in 12.4 GB VRAM and runs **31K context** on a single RTX 5080.
4
+
5
+ ## What's special
6
+
7
+ - **Full NVFP4**: all Linear layers, `lm_head`, and `embed_tokens` quantized to NVFP4
8
+ - **FP8 KV cache**: GQA attention (32 Q / 8 KV heads), stored in FP8
9
+ - **31,200-token context** on 16 GB VRAM (vs ~20K with BF16 embed)
10
+ - **12.4 GiB** single-file `model.safetensors`
11
+ - YARN rope scaling (factor=48) for long-context support
12
+ - Standard `MistralForCausalLM` architecture — no `--trust-remote-code` needed
13
+
14
+ ## Hardware
15
+
16
+ - **GPU**: NVIDIA RTX 5080 (16 GB VRAM, SM 12.0 / Blackwell)
17
+ - **NVFP4 GEMM**: Marlin backend (FlashInfer FP4 JIT fails on SM 12.0)
18
+
19
+ Should work on any Blackwell GPU (RTX 50-series, B-series datacenter). Context length scales with available VRAM.
20
+
21
+ ## Quick start
22
+
23
+ ### 1. Clone and build vLLM
24
+
25
+ ```bash
26
+ git clone https://github.com/vllm-project/vllm.git
27
+ cd vllm
28
+ git checkout 628302114 # v0.16.1rc1.dev34
29
+
30
+ # Apply patches (required for NVFP4 lm_head and embed_tokens)
31
+ git apply ../Devstral-24B-NVFP4-NVembed/vllm_patches.diff
32
+
33
+ # Build
34
+ pip install -e . --no-build-isolation
35
+ ```
36
+
37
+ ### 2. Install dependencies
38
+
39
+ ```bash
40
+ pip install flashinfer==0.6.4 # or latest compatible
41
+ ```
42
+
43
+ ### 3. Serve
44
+
45
+ ```bash
46
+ export VLLM_TEST_FORCE_FP8_MARLIN=1
47
+ export VLLM_NVFP4_GEMM_BACKEND=marlin
48
+ export PYTORCH_ALLOC_CONF=expandable_segments:True
49
+ export VLLM_FLASHINFER_WORKSPACE_BUFFER_SIZE=$((64 * 1024 * 1024))
50
+
51
+ vllm serve ./Devstral-24B-NVFP4-NVembed \
52
+ --dtype bfloat16 \
53
+ --quantization modelopt \
54
+ --kv-cache-dtype fp8_e4m3 \
55
+ --max-model-len 31200 \
56
+ --no-enable-prefix-caching \
57
+ --max-num-seqs 1 \
58
+ --kv-cache-memory-bytes $((1950 * 1310720)) \
59
+ --num-gpu-blocks-override 1950 \
60
+ --tensor-parallel-size 1 \
61
+ --enable-chunked-prefill \
62
+ --max-num-batched-tokens 256 \
63
+ --enforce-eager \
64
+ --override-generation-config '{"temperature": 0.0, "max_tokens": 8000}'
65
+ ```
66
+
67
+ ### 4. Test
68
+
69
+ ```bash
70
+ curl -s http://localhost:8000/v1/chat/completions \
71
+ -H "Content-Type: application/json" \
72
+ -d '{"model": "Devstral-24B-NVFP4-NVembed",
73
+ "messages": [{"role": "user", "content": "Write a Python function to check if a number is prime."}]}' \
74
+ | python3 -m json.tool
75
+ ```
76
+
77
+ ## Serve command flags explained
78
+
79
+ | Flag | Why |
80
+ |------|-----|
81
+ | `--quantization modelopt` | NVFP4 weight format from NVIDIA Model Optimizer |
82
+ | `--kv-cache-dtype fp8_e4m3` | FP8 KV cache — halves KV memory vs BF16 |
83
+ | `--no-enable-prefix-caching` | Disabled for maximum VRAM headroom |
84
+ | `--max-num-seqs 1` | Single sequence — 16 GB VRAM budget |
85
+ | `--kv-cache-memory-bytes` | Precise KV allocation (bypasses `gpu_memory_utilization` startup check) |
86
+ | `--num-gpu-blocks-override 1950` | Binary-searched max stable blocks for RTX 5080 |
87
+ | `--enforce-eager` | CUDA graphs disabled — saves VRAM |
88
+ | `--override-generation-config` | `temperature=0` for deterministic coding output |
89
+
90
+ ## Performance
91
+
92
+ | Metric | Value |
93
+ |--------|-------|
94
+ | Model size | 12.4 GiB |
95
+ | Max context | 31,200 tokens |
96
+ | KV cache blocks | 1,950 |
97
+ | KV cache size | ~2.4 GiB |
98
+ | KV per token | 80 KB (40 layers x 8 KV heads x 128 dim x 2 x 1 byte) |
99
+ | Architecture | Dense, 40 layers, GQA (32 Q / 8 KV heads) |
100
+ | Parameters | 24B |
101
+
102
+ ## Quantization details
103
+
104
+ - **Method**: NVIDIA Model Optimizer (`nvidia-modelopt==0.41.0`)
105
+ - **Format**: NVFP4 (4-bit floating point, group_size=16)
106
+ - **Calibration**: 512 samples across 4 task types (code, instruction, agentic, structured data from databricks-dolly-15k)
107
+ - **lm_head + embed_tokens**: also NVFP4 (saves ~1.9 GB combined)
108
+ - **Source model**: Dequantized from the original FP8 checkpoint to BF16, then quantized to NVFP4
109
+ - **Base model**: [mistralai/Devstral-Small-2-24B-Instruct](https://huggingface.co/mistralai/Devstral-Small-2-24B-Instruct)
110
+
111
+ ## vLLM patches
112
+
113
+ The included `vllm_patches.diff` modifies 3 files based on vLLM commit `628302114`:
114
+
115
+ | File | Change |
116
+ |------|--------|
117
+ | `modelopt.py` | NVFP4 `lm_head` + `embed_tokens` support; `PerTensorScaleParameter` init fix (uninitialized slots caused inf in merged linears) |
118
+ | `vocab_parallel_embedding.py` | FP8 weight dtype preservation + BF16 cast in `embedding()` |
119
+ | `linear.py` | FP8 weight cast in forward pass |
120
+
121
+ ### Upstream PRs
122
+
123
+ Some of these patches have been submitted upstream and may become unnecessary in future vLLM releases:
124
+
125
+ - [#35576](https://github.com/vllm-project/vllm/pull/35576) — MLA weight access crash fix for quantized layers
126
+ - [#35660](https://github.com/vllm-project/vllm/pull/35660) — NVFP4-quantized lm_head support
chat_template.jinja ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {#- Default system message if no system prompt is passed. #}
2
+ {%- set default_system_message = '' %}
3
+
4
+ {#- Begin of sequence token. #}
5
+ {{- bos_token }}
6
+
7
+ {#- Handle system prompt if it exists. #}
8
+ {#- System prompt supports text content or text chunks. #}
9
+ {%- if messages[0]['role'] == 'system' %}
10
+ {{- '[SYSTEM_PROMPT]' -}}
11
+ {%- if messages[0]['content'] is string %}
12
+ {{- messages[0]['content'] -}}
13
+ {%- else %}
14
+ {%- for block in messages[0]['content'] %}
15
+ {%- if block['type'] == 'text' %}
16
+ {{- block['text'] }}
17
+ {%- else %}
18
+ {{- raise_exception('Only text chunks are supported in system message contents.') }}
19
+ {%- endif %}
20
+ {%- endfor %}
21
+ {%- endif %}
22
+ {{- '[/SYSTEM_PROMPT]' -}}
23
+ {%- set loop_messages = messages[1:] %}
24
+ {%- else %}
25
+ {%- set loop_messages = messages %}
26
+ {%- if default_system_message != '' %}
27
+ {{- '[SYSTEM_PROMPT]' + default_system_message + '[/SYSTEM_PROMPT]' }}
28
+ {%- endif %}
29
+ {%- endif %}
30
+
31
+
32
+ {#- Tools definition #}
33
+ {%- set tools_definition = '' %}
34
+ {%- set has_tools = false %}
35
+ {%- if tools is defined and tools is not none and tools|length > 0 %}
36
+ {%- set has_tools = true %}
37
+ {%- set tools_definition = '[AVAILABLE_TOOLS]' + (tools| tojson) + '[/AVAILABLE_TOOLS]' %}
38
+ {{- tools_definition }}
39
+ {%- endif %}
40
+
41
+ {#- Checks for alternating user/assistant messages. #}
42
+ {%- set ns = namespace(index=0) %}
43
+ {%- for message in loop_messages %}
44
+ {%- if message.role == 'user' or (message.role == 'assistant' and (message.tool_calls is not defined or message.tool_calls is none or message.tool_calls | length == 0)) %}
45
+ {%- if (message['role'] == 'user') != (ns.index % 2 == 0) %}
46
+ {{- raise_exception('After the optional system message, conversation roles must alternate user and assistant roles except for tool calls and results.') }}
47
+ {%- endif %}
48
+ {%- set ns.index = ns.index + 1 %}
49
+ {%- endif %}
50
+ {%- endfor %}
51
+
52
+ {#- Handle conversation messages. #}
53
+ {%- for message in loop_messages %}
54
+
55
+ {#- User messages supports text content or text and image chunks. #}
56
+ {%- if message['role'] == 'user' %}
57
+ {%- if message['content'] is string %}
58
+ {{- '[INST]' + message['content'] + '[/INST]' }}
59
+ {%- elif message['content'] | length > 0 %}
60
+ {{- '[INST]' }}
61
+ {%- if message['content'] | length == 2 %}
62
+ {%- set blocks = message['content'] | sort(attribute='type') %}
63
+ {%- else %}
64
+ {%- set blocks = message['content'] %}
65
+ {%- endif %}
66
+ {%- for block in blocks %}
67
+ {%- if block['type'] == 'text' %}
68
+ {{- block['text'] }}
69
+ {%- elif block['type'] in ['image', 'image_url'] %}
70
+ {{- '[IMG]' }}
71
+ {%- else %}
72
+ {{- raise_exception('Only text, image and image_url chunks are supported in user message content.') }}
73
+ {%- endif %}
74
+ {%- endfor %}
75
+ {{- '[/INST]' }}
76
+ {%- else %}
77
+ {{- raise_exception('User message must have a string or a list of chunks in content') }}
78
+ {%- endif %}
79
+
80
+ {#- Assistant messages supports text content or text and image chunks. #}
81
+ {%- elif message['role'] == 'assistant' %}
82
+ {%- if (message['content'] is none or message['content'] == '' or message['content']|length == 0) and (message['tool_calls'] is not defined or message['tool_calls'] is none or message['tool_calls']|length == 0) %}
83
+ {{- raise_exception('Assistant message must have a string or a list of chunks in content or a list of tool calls.') }}
84
+ {%- endif %}
85
+
86
+ {%- if message['content'] is string %}
87
+ {{- message['content'] }}
88
+ {%- elif message['content'] | length > 0 %}
89
+ {%- for block in message['content'] %}
90
+ {%- if block['type'] == 'text' %}
91
+ {{- block['text'] }}
92
+ {%- else %}
93
+ {{- raise_exception('Only text chunks are supported in assistant message contents.') }}
94
+ {%- endif %}
95
+ {%- endfor %}
96
+ {%- endif %}
97
+
98
+ {%- if message['tool_calls'] is defined and message['tool_calls'] is not none and message['tool_calls']|length > 0 %}
99
+ {%- for tool in message['tool_calls'] %}
100
+ {%- set arguments = tool['function']['arguments'] %}
101
+ {%- if arguments is not string %}
102
+ {%- set arguments = arguments|tojson|safe %}
103
+ {%- elif arguments == '' %}
104
+ {%- set arguments = '{}' %}
105
+ {%- endif %}
106
+ {{- '[TOOL_CALLS]' + tool['function']['name'] + '[ARGS]' + arguments }}
107
+ {%- endfor %}
108
+ {%- endif %}
109
+
110
+ {#- End of sequence token for each assistant messages. #}
111
+ {{- eos_token }}
112
+
113
+ {#- Tool messages only supports text content. #}
114
+ {%- elif message['role'] == 'tool' %}
115
+ {{- '[TOOL_RESULTS]' + message['content']|string + '[/TOOL_RESULTS]' }}
116
+
117
+ {#- Raise exception for unsupported roles. #}
118
+ {%- else %}
119
+ {{- raise_exception('Only user, assistant and tool roles are supported, got ' + message['role'] + '.') }}
120
+ {%- endif %}
121
+ {%- endfor %}
config.json ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "MistralForCausalLM"
4
+ ],
5
+ "attention_dropout": 0.0,
6
+ "bos_token_id": 1,
7
+ "dtype": "bfloat16",
8
+ "eos_token_id": 2,
9
+ "head_dim": 128,
10
+ "hidden_act": "silu",
11
+ "hidden_size": 5120,
12
+ "initializer_range": 0.02,
13
+ "intermediate_size": 32768,
14
+ "max_position_embeddings": 393216,
15
+ "model_type": "mistral",
16
+ "num_attention_heads": 32,
17
+ "num_hidden_layers": 40,
18
+ "num_key_value_heads": 8,
19
+ "pad_token_id": null,
20
+ "rms_norm_eps": 1e-05,
21
+ "rope_parameters": {
22
+ "beta_fast": 32.0,
23
+ "beta_slow": 1.0,
24
+ "factor": 48.0,
25
+ "llama_4_scaling_beta": 0.1,
26
+ "mscale": 1.0,
27
+ "mscale_all_dim": 1.0,
28
+ "original_max_position_embeddings": 8192,
29
+ "rope_theta": 100000000.0,
30
+ "rope_type": "yarn",
31
+ "type": "yarn"
32
+ },
33
+ "sliding_window": null,
34
+ "tie_word_embeddings": false,
35
+ "transformers_version": "5.2.0",
36
+ "use_cache": true,
37
+ "vocab_size": 131072,
38
+ "quantization_config": {
39
+ "config_groups": {
40
+ "group_0": {
41
+ "input_activations": {
42
+ "dynamic": false,
43
+ "num_bits": 4,
44
+ "type": "float",
45
+ "group_size": 16
46
+ },
47
+ "weights": {
48
+ "dynamic": false,
49
+ "num_bits": 4,
50
+ "type": "float",
51
+ "group_size": 16
52
+ },
53
+ "targets": [
54
+ "Linear"
55
+ ]
56
+ }
57
+ },
58
+ "ignore": [],
59
+ "quant_algo": "NVFP4",
60
+ "producer": {
61
+ "name": "modelopt",
62
+ "version": "0.41.0"
63
+ },
64
+ "quant_method": "modelopt",
65
+ "nvfp4_embed": true
66
+ },
67
+ "rope_scaling": {
68
+ "beta_fast": 32.0,
69
+ "beta_slow": 1.0,
70
+ "factor": 48.0,
71
+ "llama_4_scaling_beta": 0.1,
72
+ "mscale": 1.0,
73
+ "mscale_all_dim": 1.0,
74
+ "original_max_position_embeddings": 8192,
75
+ "rope_theta": 100000000.0,
76
+ "rope_type": "yarn",
77
+ "type": "yarn"
78
+ }
79
+ }
generation_config.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "transformers_version": "5.2.0",
4
+ "use_cache": true
5
+ }
hf_quant_config.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "producer": {
3
+ "name": "modelopt",
4
+ "version": "0.41.0"
5
+ },
6
+ "quantization": {
7
+ "quant_algo": "NVFP4",
8
+ "kv_cache_quant_algo": null,
9
+ "group_size": 16,
10
+ "exclude_modules": [],
11
+ "nvfp4_embed": true
12
+ }
13
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4c7f9d376ec578ce2934e9db65bf58508ab738fd8e01db3da4d41830cedca88c
3
+ size 13260207288
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c05b883079bc2f8083f6478bd21f8b4b38c82bf598c3eb6a804b323ab59e5c19
3
+ size 17077501
tokenizer_config.json ADDED
@@ -0,0 +1,1013 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "bos_token": "<s>",
4
+ "eos_token": "</s>",
5
+ "extra_special_tokens": [
6
+ "<unk>",
7
+ "<s>",
8
+ "</s>",
9
+ "[INST]",
10
+ "[/INST]",
11
+ "[AVAILABLE_TOOLS]",
12
+ "[/AVAILABLE_TOOLS]",
13
+ "[TOOL_RESULTS]",
14
+ "[/TOOL_RESULTS]",
15
+ "[TOOL_CALLS]",
16
+ "[IMG]",
17
+ "<pad>",
18
+ "[IMG_BREAK]",
19
+ "[IMG_END]",
20
+ "[PREFIX]",
21
+ "[MIDDLE]",
22
+ "[SUFFIX]",
23
+ "[SYSTEM_PROMPT]",
24
+ "[/SYSTEM_PROMPT]",
25
+ "[TOOL_CONTENT]",
26
+ "<SPECIAL_20>",
27
+ "<SPECIAL_21>",
28
+ "<SPECIAL_22>",
29
+ "<SPECIAL_23>",
30
+ "[AUDIO]",
31
+ "[BEGIN_AUDIO]",
32
+ "<SPECIAL_26>",
33
+ "<SPECIAL_27>",
34
+ "<SPECIAL_28>",
35
+ "<SPECIAL_29>",
36
+ "<SPECIAL_30>",
37
+ "<SPECIAL_31>",
38
+ "[ARGS]",
39
+ "[CALL_ID]",
40
+ "[THINK]",
41
+ "[/THINK]",
42
+ "<SPECIAL_36>",
43
+ "<SPECIAL_37>",
44
+ "<SPECIAL_38>",
45
+ "<SPECIAL_39>",
46
+ "<SPECIAL_40>",
47
+ "<SPECIAL_41>",
48
+ "<SPECIAL_42>",
49
+ "<SPECIAL_43>",
50
+ "<SPECIAL_44>",
51
+ "<SPECIAL_45>",
52
+ "<SPECIAL_46>",
53
+ "<SPECIAL_47>",
54
+ "<SPECIAL_48>",
55
+ "<SPECIAL_49>",
56
+ "<SPECIAL_50>",
57
+ "<SPECIAL_51>",
58
+ "<SPECIAL_52>",
59
+ "<SPECIAL_53>",
60
+ "<SPECIAL_54>",
61
+ "<SPECIAL_55>",
62
+ "<SPECIAL_56>",
63
+ "<SPECIAL_57>",
64
+ "<SPECIAL_58>",
65
+ "<SPECIAL_59>",
66
+ "<SPECIAL_60>",
67
+ "<SPECIAL_61>",
68
+ "<SPECIAL_62>",
69
+ "<SPECIAL_63>",
70
+ "<SPECIAL_64>",
71
+ "<SPECIAL_65>",
72
+ "<SPECIAL_66>",
73
+ "<SPECIAL_67>",
74
+ "<SPECIAL_68>",
75
+ "<SPECIAL_69>",
76
+ "<SPECIAL_70>",
77
+ "<SPECIAL_71>",
78
+ "<SPECIAL_72>",
79
+ "<SPECIAL_73>",
80
+ "<SPECIAL_74>",
81
+ "<SPECIAL_75>",
82
+ "<SPECIAL_76>",
83
+ "<SPECIAL_77>",
84
+ "<SPECIAL_78>",
85
+ "<SPECIAL_79>",
86
+ "<SPECIAL_80>",
87
+ "<SPECIAL_81>",
88
+ "<SPECIAL_82>",
89
+ "<SPECIAL_83>",
90
+ "<SPECIAL_84>",
91
+ "<SPECIAL_85>",
92
+ "<SPECIAL_86>",
93
+ "<SPECIAL_87>",
94
+ "<SPECIAL_88>",
95
+ "<SPECIAL_89>",
96
+ "<SPECIAL_90>",
97
+ "<SPECIAL_91>",
98
+ "<SPECIAL_92>",
99
+ "<SPECIAL_93>",
100
+ "<SPECIAL_94>",
101
+ "<SPECIAL_95>",
102
+ "<SPECIAL_96>",
103
+ "<SPECIAL_97>",
104
+ "<SPECIAL_98>",
105
+ "<SPECIAL_99>",
106
+ "<SPECIAL_100>",
107
+ "<SPECIAL_101>",
108
+ "<SPECIAL_102>",
109
+ "<SPECIAL_103>",
110
+ "<SPECIAL_104>",
111
+ "<SPECIAL_105>",
112
+ "<SPECIAL_106>",
113
+ "<SPECIAL_107>",
114
+ "<SPECIAL_108>",
115
+ "<SPECIAL_109>",
116
+ "<SPECIAL_110>",
117
+ "<SPECIAL_111>",
118
+ "<SPECIAL_112>",
119
+ "<SPECIAL_113>",
120
+ "<SPECIAL_114>",
121
+ "<SPECIAL_115>",
122
+ "<SPECIAL_116>",
123
+ "<SPECIAL_117>",
124
+ "<SPECIAL_118>",
125
+ "<SPECIAL_119>",
126
+ "<SPECIAL_120>",
127
+ "<SPECIAL_121>",
128
+ "<SPECIAL_122>",
129
+ "<SPECIAL_123>",
130
+ "<SPECIAL_124>",
131
+ "<SPECIAL_125>",
132
+ "<SPECIAL_126>",
133
+ "<SPECIAL_127>",
134
+ "<SPECIAL_128>",
135
+ "<SPECIAL_129>",
136
+ "<SPECIAL_130>",
137
+ "<SPECIAL_131>",
138
+ "<SPECIAL_132>",
139
+ "<SPECIAL_133>",
140
+ "<SPECIAL_134>",
141
+ "<SPECIAL_135>",
142
+ "<SPECIAL_136>",
143
+ "<SPECIAL_137>",
144
+ "<SPECIAL_138>",
145
+ "<SPECIAL_139>",
146
+ "<SPECIAL_140>",
147
+ "<SPECIAL_141>",
148
+ "<SPECIAL_142>",
149
+ "<SPECIAL_143>",
150
+ "<SPECIAL_144>",
151
+ "<SPECIAL_145>",
152
+ "<SPECIAL_146>",
153
+ "<SPECIAL_147>",
154
+ "<SPECIAL_148>",
155
+ "<SPECIAL_149>",
156
+ "<SPECIAL_150>",
157
+ "<SPECIAL_151>",
158
+ "<SPECIAL_152>",
159
+ "<SPECIAL_153>",
160
+ "<SPECIAL_154>",
161
+ "<SPECIAL_155>",
162
+ "<SPECIAL_156>",
163
+ "<SPECIAL_157>",
164
+ "<SPECIAL_158>",
165
+ "<SPECIAL_159>",
166
+ "<SPECIAL_160>",
167
+ "<SPECIAL_161>",
168
+ "<SPECIAL_162>",
169
+ "<SPECIAL_163>",
170
+ "<SPECIAL_164>",
171
+ "<SPECIAL_165>",
172
+ "<SPECIAL_166>",
173
+ "<SPECIAL_167>",
174
+ "<SPECIAL_168>",
175
+ "<SPECIAL_169>",
176
+ "<SPECIAL_170>",
177
+ "<SPECIAL_171>",
178
+ "<SPECIAL_172>",
179
+ "<SPECIAL_173>",
180
+ "<SPECIAL_174>",
181
+ "<SPECIAL_175>",
182
+ "<SPECIAL_176>",
183
+ "<SPECIAL_177>",
184
+ "<SPECIAL_178>",
185
+ "<SPECIAL_179>",
186
+ "<SPECIAL_180>",
187
+ "<SPECIAL_181>",
188
+ "<SPECIAL_182>",
189
+ "<SPECIAL_183>",
190
+ "<SPECIAL_184>",
191
+ "<SPECIAL_185>",
192
+ "<SPECIAL_186>",
193
+ "<SPECIAL_187>",
194
+ "<SPECIAL_188>",
195
+ "<SPECIAL_189>",
196
+ "<SPECIAL_190>",
197
+ "<SPECIAL_191>",
198
+ "<SPECIAL_192>",
199
+ "<SPECIAL_193>",
200
+ "<SPECIAL_194>",
201
+ "<SPECIAL_195>",
202
+ "<SPECIAL_196>",
203
+ "<SPECIAL_197>",
204
+ "<SPECIAL_198>",
205
+ "<SPECIAL_199>",
206
+ "<SPECIAL_200>",
207
+ "<SPECIAL_201>",
208
+ "<SPECIAL_202>",
209
+ "<SPECIAL_203>",
210
+ "<SPECIAL_204>",
211
+ "<SPECIAL_205>",
212
+ "<SPECIAL_206>",
213
+ "<SPECIAL_207>",
214
+ "<SPECIAL_208>",
215
+ "<SPECIAL_209>",
216
+ "<SPECIAL_210>",
217
+ "<SPECIAL_211>",
218
+ "<SPECIAL_212>",
219
+ "<SPECIAL_213>",
220
+ "<SPECIAL_214>",
221
+ "<SPECIAL_215>",
222
+ "<SPECIAL_216>",
223
+ "<SPECIAL_217>",
224
+ "<SPECIAL_218>",
225
+ "<SPECIAL_219>",
226
+ "<SPECIAL_220>",
227
+ "<SPECIAL_221>",
228
+ "<SPECIAL_222>",
229
+ "<SPECIAL_223>",
230
+ "<SPECIAL_224>",
231
+ "<SPECIAL_225>",
232
+ "<SPECIAL_226>",
233
+ "<SPECIAL_227>",
234
+ "<SPECIAL_228>",
235
+ "<SPECIAL_229>",
236
+ "<SPECIAL_230>",
237
+ "<SPECIAL_231>",
238
+ "<SPECIAL_232>",
239
+ "<SPECIAL_233>",
240
+ "<SPECIAL_234>",
241
+ "<SPECIAL_235>",
242
+ "<SPECIAL_236>",
243
+ "<SPECIAL_237>",
244
+ "<SPECIAL_238>",
245
+ "<SPECIAL_239>",
246
+ "<SPECIAL_240>",
247
+ "<SPECIAL_241>",
248
+ "<SPECIAL_242>",
249
+ "<SPECIAL_243>",
250
+ "<SPECIAL_244>",
251
+ "<SPECIAL_245>",
252
+ "<SPECIAL_246>",
253
+ "<SPECIAL_247>",
254
+ "<SPECIAL_248>",
255
+ "<SPECIAL_249>",
256
+ "<SPECIAL_250>",
257
+ "<SPECIAL_251>",
258
+ "<SPECIAL_252>",
259
+ "<SPECIAL_253>",
260
+ "<SPECIAL_254>",
261
+ "<SPECIAL_255>",
262
+ "<SPECIAL_256>",
263
+ "<SPECIAL_257>",
264
+ "<SPECIAL_258>",
265
+ "<SPECIAL_259>",
266
+ "<SPECIAL_260>",
267
+ "<SPECIAL_261>",
268
+ "<SPECIAL_262>",
269
+ "<SPECIAL_263>",
270
+ "<SPECIAL_264>",
271
+ "<SPECIAL_265>",
272
+ "<SPECIAL_266>",
273
+ "<SPECIAL_267>",
274
+ "<SPECIAL_268>",
275
+ "<SPECIAL_269>",
276
+ "<SPECIAL_270>",
277
+ "<SPECIAL_271>",
278
+ "<SPECIAL_272>",
279
+ "<SPECIAL_273>",
280
+ "<SPECIAL_274>",
281
+ "<SPECIAL_275>",
282
+ "<SPECIAL_276>",
283
+ "<SPECIAL_277>",
284
+ "<SPECIAL_278>",
285
+ "<SPECIAL_279>",
286
+ "<SPECIAL_280>",
287
+ "<SPECIAL_281>",
288
+ "<SPECIAL_282>",
289
+ "<SPECIAL_283>",
290
+ "<SPECIAL_284>",
291
+ "<SPECIAL_285>",
292
+ "<SPECIAL_286>",
293
+ "<SPECIAL_287>",
294
+ "<SPECIAL_288>",
295
+ "<SPECIAL_289>",
296
+ "<SPECIAL_290>",
297
+ "<SPECIAL_291>",
298
+ "<SPECIAL_292>",
299
+ "<SPECIAL_293>",
300
+ "<SPECIAL_294>",
301
+ "<SPECIAL_295>",
302
+ "<SPECIAL_296>",
303
+ "<SPECIAL_297>",
304
+ "<SPECIAL_298>",
305
+ "<SPECIAL_299>",
306
+ "<SPECIAL_300>",
307
+ "<SPECIAL_301>",
308
+ "<SPECIAL_302>",
309
+ "<SPECIAL_303>",
310
+ "<SPECIAL_304>",
311
+ "<SPECIAL_305>",
312
+ "<SPECIAL_306>",
313
+ "<SPECIAL_307>",
314
+ "<SPECIAL_308>",
315
+ "<SPECIAL_309>",
316
+ "<SPECIAL_310>",
317
+ "<SPECIAL_311>",
318
+ "<SPECIAL_312>",
319
+ "<SPECIAL_313>",
320
+ "<SPECIAL_314>",
321
+ "<SPECIAL_315>",
322
+ "<SPECIAL_316>",
323
+ "<SPECIAL_317>",
324
+ "<SPECIAL_318>",
325
+ "<SPECIAL_319>",
326
+ "<SPECIAL_320>",
327
+ "<SPECIAL_321>",
328
+ "<SPECIAL_322>",
329
+ "<SPECIAL_323>",
330
+ "<SPECIAL_324>",
331
+ "<SPECIAL_325>",
332
+ "<SPECIAL_326>",
333
+ "<SPECIAL_327>",
334
+ "<SPECIAL_328>",
335
+ "<SPECIAL_329>",
336
+ "<SPECIAL_330>",
337
+ "<SPECIAL_331>",
338
+ "<SPECIAL_332>",
339
+ "<SPECIAL_333>",
340
+ "<SPECIAL_334>",
341
+ "<SPECIAL_335>",
342
+ "<SPECIAL_336>",
343
+ "<SPECIAL_337>",
344
+ "<SPECIAL_338>",
345
+ "<SPECIAL_339>",
346
+ "<SPECIAL_340>",
347
+ "<SPECIAL_341>",
348
+ "<SPECIAL_342>",
349
+ "<SPECIAL_343>",
350
+ "<SPECIAL_344>",
351
+ "<SPECIAL_345>",
352
+ "<SPECIAL_346>",
353
+ "<SPECIAL_347>",
354
+ "<SPECIAL_348>",
355
+ "<SPECIAL_349>",
356
+ "<SPECIAL_350>",
357
+ "<SPECIAL_351>",
358
+ "<SPECIAL_352>",
359
+ "<SPECIAL_353>",
360
+ "<SPECIAL_354>",
361
+ "<SPECIAL_355>",
362
+ "<SPECIAL_356>",
363
+ "<SPECIAL_357>",
364
+ "<SPECIAL_358>",
365
+ "<SPECIAL_359>",
366
+ "<SPECIAL_360>",
367
+ "<SPECIAL_361>",
368
+ "<SPECIAL_362>",
369
+ "<SPECIAL_363>",
370
+ "<SPECIAL_364>",
371
+ "<SPECIAL_365>",
372
+ "<SPECIAL_366>",
373
+ "<SPECIAL_367>",
374
+ "<SPECIAL_368>",
375
+ "<SPECIAL_369>",
376
+ "<SPECIAL_370>",
377
+ "<SPECIAL_371>",
378
+ "<SPECIAL_372>",
379
+ "<SPECIAL_373>",
380
+ "<SPECIAL_374>",
381
+ "<SPECIAL_375>",
382
+ "<SPECIAL_376>",
383
+ "<SPECIAL_377>",
384
+ "<SPECIAL_378>",
385
+ "<SPECIAL_379>",
386
+ "<SPECIAL_380>",
387
+ "<SPECIAL_381>",
388
+ "<SPECIAL_382>",
389
+ "<SPECIAL_383>",
390
+ "<SPECIAL_384>",
391
+ "<SPECIAL_385>",
392
+ "<SPECIAL_386>",
393
+ "<SPECIAL_387>",
394
+ "<SPECIAL_388>",
395
+ "<SPECIAL_389>",
396
+ "<SPECIAL_390>",
397
+ "<SPECIAL_391>",
398
+ "<SPECIAL_392>",
399
+ "<SPECIAL_393>",
400
+ "<SPECIAL_394>",
401
+ "<SPECIAL_395>",
402
+ "<SPECIAL_396>",
403
+ "<SPECIAL_397>",
404
+ "<SPECIAL_398>",
405
+ "<SPECIAL_399>",
406
+ "<SPECIAL_400>",
407
+ "<SPECIAL_401>",
408
+ "<SPECIAL_402>",
409
+ "<SPECIAL_403>",
410
+ "<SPECIAL_404>",
411
+ "<SPECIAL_405>",
412
+ "<SPECIAL_406>",
413
+ "<SPECIAL_407>",
414
+ "<SPECIAL_408>",
415
+ "<SPECIAL_409>",
416
+ "<SPECIAL_410>",
417
+ "<SPECIAL_411>",
418
+ "<SPECIAL_412>",
419
+ "<SPECIAL_413>",
420
+ "<SPECIAL_414>",
421
+ "<SPECIAL_415>",
422
+ "<SPECIAL_416>",
423
+ "<SPECIAL_417>",
424
+ "<SPECIAL_418>",
425
+ "<SPECIAL_419>",
426
+ "<SPECIAL_420>",
427
+ "<SPECIAL_421>",
428
+ "<SPECIAL_422>",
429
+ "<SPECIAL_423>",
430
+ "<SPECIAL_424>",
431
+ "<SPECIAL_425>",
432
+ "<SPECIAL_426>",
433
+ "<SPECIAL_427>",
434
+ "<SPECIAL_428>",
435
+ "<SPECIAL_429>",
436
+ "<SPECIAL_430>",
437
+ "<SPECIAL_431>",
438
+ "<SPECIAL_432>",
439
+ "<SPECIAL_433>",
440
+ "<SPECIAL_434>",
441
+ "<SPECIAL_435>",
442
+ "<SPECIAL_436>",
443
+ "<SPECIAL_437>",
444
+ "<SPECIAL_438>",
445
+ "<SPECIAL_439>",
446
+ "<SPECIAL_440>",
447
+ "<SPECIAL_441>",
448
+ "<SPECIAL_442>",
449
+ "<SPECIAL_443>",
450
+ "<SPECIAL_444>",
451
+ "<SPECIAL_445>",
452
+ "<SPECIAL_446>",
453
+ "<SPECIAL_447>",
454
+ "<SPECIAL_448>",
455
+ "<SPECIAL_449>",
456
+ "<SPECIAL_450>",
457
+ "<SPECIAL_451>",
458
+ "<SPECIAL_452>",
459
+ "<SPECIAL_453>",
460
+ "<SPECIAL_454>",
461
+ "<SPECIAL_455>",
462
+ "<SPECIAL_456>",
463
+ "<SPECIAL_457>",
464
+ "<SPECIAL_458>",
465
+ "<SPECIAL_459>",
466
+ "<SPECIAL_460>",
467
+ "<SPECIAL_461>",
468
+ "<SPECIAL_462>",
469
+ "<SPECIAL_463>",
470
+ "<SPECIAL_464>",
471
+ "<SPECIAL_465>",
472
+ "<SPECIAL_466>",
473
+ "<SPECIAL_467>",
474
+ "<SPECIAL_468>",
475
+ "<SPECIAL_469>",
476
+ "<SPECIAL_470>",
477
+ "<SPECIAL_471>",
478
+ "<SPECIAL_472>",
479
+ "<SPECIAL_473>",
480
+ "<SPECIAL_474>",
481
+ "<SPECIAL_475>",
482
+ "<SPECIAL_476>",
483
+ "<SPECIAL_477>",
484
+ "<SPECIAL_478>",
485
+ "<SPECIAL_479>",
486
+ "<SPECIAL_480>",
487
+ "<SPECIAL_481>",
488
+ "<SPECIAL_482>",
489
+ "<SPECIAL_483>",
490
+ "<SPECIAL_484>",
491
+ "<SPECIAL_485>",
492
+ "<SPECIAL_486>",
493
+ "<SPECIAL_487>",
494
+ "<SPECIAL_488>",
495
+ "<SPECIAL_489>",
496
+ "<SPECIAL_490>",
497
+ "<SPECIAL_491>",
498
+ "<SPECIAL_492>",
499
+ "<SPECIAL_493>",
500
+ "<SPECIAL_494>",
501
+ "<SPECIAL_495>",
502
+ "<SPECIAL_496>",
503
+ "<SPECIAL_497>",
504
+ "<SPECIAL_498>",
505
+ "<SPECIAL_499>",
506
+ "<SPECIAL_500>",
507
+ "<SPECIAL_501>",
508
+ "<SPECIAL_502>",
509
+ "<SPECIAL_503>",
510
+ "<SPECIAL_504>",
511
+ "<SPECIAL_505>",
512
+ "<SPECIAL_506>",
513
+ "<SPECIAL_507>",
514
+ "<SPECIAL_508>",
515
+ "<SPECIAL_509>",
516
+ "<SPECIAL_510>",
517
+ "<SPECIAL_511>",
518
+ "<SPECIAL_512>",
519
+ "<SPECIAL_513>",
520
+ "<SPECIAL_514>",
521
+ "<SPECIAL_515>",
522
+ "<SPECIAL_516>",
523
+ "<SPECIAL_517>",
524
+ "<SPECIAL_518>",
525
+ "<SPECIAL_519>",
526
+ "<SPECIAL_520>",
527
+ "<SPECIAL_521>",
528
+ "<SPECIAL_522>",
529
+ "<SPECIAL_523>",
530
+ "<SPECIAL_524>",
531
+ "<SPECIAL_525>",
532
+ "<SPECIAL_526>",
533
+ "<SPECIAL_527>",
534
+ "<SPECIAL_528>",
535
+ "<SPECIAL_529>",
536
+ "<SPECIAL_530>",
537
+ "<SPECIAL_531>",
538
+ "<SPECIAL_532>",
539
+ "<SPECIAL_533>",
540
+ "<SPECIAL_534>",
541
+ "<SPECIAL_535>",
542
+ "<SPECIAL_536>",
543
+ "<SPECIAL_537>",
544
+ "<SPECIAL_538>",
545
+ "<SPECIAL_539>",
546
+ "<SPECIAL_540>",
547
+ "<SPECIAL_541>",
548
+ "<SPECIAL_542>",
549
+ "<SPECIAL_543>",
550
+ "<SPECIAL_544>",
551
+ "<SPECIAL_545>",
552
+ "<SPECIAL_546>",
553
+ "<SPECIAL_547>",
554
+ "<SPECIAL_548>",
555
+ "<SPECIAL_549>",
556
+ "<SPECIAL_550>",
557
+ "<SPECIAL_551>",
558
+ "<SPECIAL_552>",
559
+ "<SPECIAL_553>",
560
+ "<SPECIAL_554>",
561
+ "<SPECIAL_555>",
562
+ "<SPECIAL_556>",
563
+ "<SPECIAL_557>",
564
+ "<SPECIAL_558>",
565
+ "<SPECIAL_559>",
566
+ "<SPECIAL_560>",
567
+ "<SPECIAL_561>",
568
+ "<SPECIAL_562>",
569
+ "<SPECIAL_563>",
570
+ "<SPECIAL_564>",
571
+ "<SPECIAL_565>",
572
+ "<SPECIAL_566>",
573
+ "<SPECIAL_567>",
574
+ "<SPECIAL_568>",
575
+ "<SPECIAL_569>",
576
+ "<SPECIAL_570>",
577
+ "<SPECIAL_571>",
578
+ "<SPECIAL_572>",
579
+ "<SPECIAL_573>",
580
+ "<SPECIAL_574>",
581
+ "<SPECIAL_575>",
582
+ "<SPECIAL_576>",
583
+ "<SPECIAL_577>",
584
+ "<SPECIAL_578>",
585
+ "<SPECIAL_579>",
586
+ "<SPECIAL_580>",
587
+ "<SPECIAL_581>",
588
+ "<SPECIAL_582>",
589
+ "<SPECIAL_583>",
590
+ "<SPECIAL_584>",
591
+ "<SPECIAL_585>",
592
+ "<SPECIAL_586>",
593
+ "<SPECIAL_587>",
594
+ "<SPECIAL_588>",
595
+ "<SPECIAL_589>",
596
+ "<SPECIAL_590>",
597
+ "<SPECIAL_591>",
598
+ "<SPECIAL_592>",
599
+ "<SPECIAL_593>",
600
+ "<SPECIAL_594>",
601
+ "<SPECIAL_595>",
602
+ "<SPECIAL_596>",
603
+ "<SPECIAL_597>",
604
+ "<SPECIAL_598>",
605
+ "<SPECIAL_599>",
606
+ "<SPECIAL_600>",
607
+ "<SPECIAL_601>",
608
+ "<SPECIAL_602>",
609
+ "<SPECIAL_603>",
610
+ "<SPECIAL_604>",
611
+ "<SPECIAL_605>",
612
+ "<SPECIAL_606>",
613
+ "<SPECIAL_607>",
614
+ "<SPECIAL_608>",
615
+ "<SPECIAL_609>",
616
+ "<SPECIAL_610>",
617
+ "<SPECIAL_611>",
618
+ "<SPECIAL_612>",
619
+ "<SPECIAL_613>",
620
+ "<SPECIAL_614>",
621
+ "<SPECIAL_615>",
622
+ "<SPECIAL_616>",
623
+ "<SPECIAL_617>",
624
+ "<SPECIAL_618>",
625
+ "<SPECIAL_619>",
626
+ "<SPECIAL_620>",
627
+ "<SPECIAL_621>",
628
+ "<SPECIAL_622>",
629
+ "<SPECIAL_623>",
630
+ "<SPECIAL_624>",
631
+ "<SPECIAL_625>",
632
+ "<SPECIAL_626>",
633
+ "<SPECIAL_627>",
634
+ "<SPECIAL_628>",
635
+ "<SPECIAL_629>",
636
+ "<SPECIAL_630>",
637
+ "<SPECIAL_631>",
638
+ "<SPECIAL_632>",
639
+ "<SPECIAL_633>",
640
+ "<SPECIAL_634>",
641
+ "<SPECIAL_635>",
642
+ "<SPECIAL_636>",
643
+ "<SPECIAL_637>",
644
+ "<SPECIAL_638>",
645
+ "<SPECIAL_639>",
646
+ "<SPECIAL_640>",
647
+ "<SPECIAL_641>",
648
+ "<SPECIAL_642>",
649
+ "<SPECIAL_643>",
650
+ "<SPECIAL_644>",
651
+ "<SPECIAL_645>",
652
+ "<SPECIAL_646>",
653
+ "<SPECIAL_647>",
654
+ "<SPECIAL_648>",
655
+ "<SPECIAL_649>",
656
+ "<SPECIAL_650>",
657
+ "<SPECIAL_651>",
658
+ "<SPECIAL_652>",
659
+ "<SPECIAL_653>",
660
+ "<SPECIAL_654>",
661
+ "<SPECIAL_655>",
662
+ "<SPECIAL_656>",
663
+ "<SPECIAL_657>",
664
+ "<SPECIAL_658>",
665
+ "<SPECIAL_659>",
666
+ "<SPECIAL_660>",
667
+ "<SPECIAL_661>",
668
+ "<SPECIAL_662>",
669
+ "<SPECIAL_663>",
670
+ "<SPECIAL_664>",
671
+ "<SPECIAL_665>",
672
+ "<SPECIAL_666>",
673
+ "<SPECIAL_667>",
674
+ "<SPECIAL_668>",
675
+ "<SPECIAL_669>",
676
+ "<SPECIAL_670>",
677
+ "<SPECIAL_671>",
678
+ "<SPECIAL_672>",
679
+ "<SPECIAL_673>",
680
+ "<SPECIAL_674>",
681
+ "<SPECIAL_675>",
682
+ "<SPECIAL_676>",
683
+ "<SPECIAL_677>",
684
+ "<SPECIAL_678>",
685
+ "<SPECIAL_679>",
686
+ "<SPECIAL_680>",
687
+ "<SPECIAL_681>",
688
+ "<SPECIAL_682>",
689
+ "<SPECIAL_683>",
690
+ "<SPECIAL_684>",
691
+ "<SPECIAL_685>",
692
+ "<SPECIAL_686>",
693
+ "<SPECIAL_687>",
694
+ "<SPECIAL_688>",
695
+ "<SPECIAL_689>",
696
+ "<SPECIAL_690>",
697
+ "<SPECIAL_691>",
698
+ "<SPECIAL_692>",
699
+ "<SPECIAL_693>",
700
+ "<SPECIAL_694>",
701
+ "<SPECIAL_695>",
702
+ "<SPECIAL_696>",
703
+ "<SPECIAL_697>",
704
+ "<SPECIAL_698>",
705
+ "<SPECIAL_699>",
706
+ "<SPECIAL_700>",
707
+ "<SPECIAL_701>",
708
+ "<SPECIAL_702>",
709
+ "<SPECIAL_703>",
710
+ "<SPECIAL_704>",
711
+ "<SPECIAL_705>",
712
+ "<SPECIAL_706>",
713
+ "<SPECIAL_707>",
714
+ "<SPECIAL_708>",
715
+ "<SPECIAL_709>",
716
+ "<SPECIAL_710>",
717
+ "<SPECIAL_711>",
718
+ "<SPECIAL_712>",
719
+ "<SPECIAL_713>",
720
+ "<SPECIAL_714>",
721
+ "<SPECIAL_715>",
722
+ "<SPECIAL_716>",
723
+ "<SPECIAL_717>",
724
+ "<SPECIAL_718>",
725
+ "<SPECIAL_719>",
726
+ "<SPECIAL_720>",
727
+ "<SPECIAL_721>",
728
+ "<SPECIAL_722>",
729
+ "<SPECIAL_723>",
730
+ "<SPECIAL_724>",
731
+ "<SPECIAL_725>",
732
+ "<SPECIAL_726>",
733
+ "<SPECIAL_727>",
734
+ "<SPECIAL_728>",
735
+ "<SPECIAL_729>",
736
+ "<SPECIAL_730>",
737
+ "<SPECIAL_731>",
738
+ "<SPECIAL_732>",
739
+ "<SPECIAL_733>",
740
+ "<SPECIAL_734>",
741
+ "<SPECIAL_735>",
742
+ "<SPECIAL_736>",
743
+ "<SPECIAL_737>",
744
+ "<SPECIAL_738>",
745
+ "<SPECIAL_739>",
746
+ "<SPECIAL_740>",
747
+ "<SPECIAL_741>",
748
+ "<SPECIAL_742>",
749
+ "<SPECIAL_743>",
750
+ "<SPECIAL_744>",
751
+ "<SPECIAL_745>",
752
+ "<SPECIAL_746>",
753
+ "<SPECIAL_747>",
754
+ "<SPECIAL_748>",
755
+ "<SPECIAL_749>",
756
+ "<SPECIAL_750>",
757
+ "<SPECIAL_751>",
758
+ "<SPECIAL_752>",
759
+ "<SPECIAL_753>",
760
+ "<SPECIAL_754>",
761
+ "<SPECIAL_755>",
762
+ "<SPECIAL_756>",
763
+ "<SPECIAL_757>",
764
+ "<SPECIAL_758>",
765
+ "<SPECIAL_759>",
766
+ "<SPECIAL_760>",
767
+ "<SPECIAL_761>",
768
+ "<SPECIAL_762>",
769
+ "<SPECIAL_763>",
770
+ "<SPECIAL_764>",
771
+ "<SPECIAL_765>",
772
+ "<SPECIAL_766>",
773
+ "<SPECIAL_767>",
774
+ "<SPECIAL_768>",
775
+ "<SPECIAL_769>",
776
+ "<SPECIAL_770>",
777
+ "<SPECIAL_771>",
778
+ "<SPECIAL_772>",
779
+ "<SPECIAL_773>",
780
+ "<SPECIAL_774>",
781
+ "<SPECIAL_775>",
782
+ "<SPECIAL_776>",
783
+ "<SPECIAL_777>",
784
+ "<SPECIAL_778>",
785
+ "<SPECIAL_779>",
786
+ "<SPECIAL_780>",
787
+ "<SPECIAL_781>",
788
+ "<SPECIAL_782>",
789
+ "<SPECIAL_783>",
790
+ "<SPECIAL_784>",
791
+ "<SPECIAL_785>",
792
+ "<SPECIAL_786>",
793
+ "<SPECIAL_787>",
794
+ "<SPECIAL_788>",
795
+ "<SPECIAL_789>",
796
+ "<SPECIAL_790>",
797
+ "<SPECIAL_791>",
798
+ "<SPECIAL_792>",
799
+ "<SPECIAL_793>",
800
+ "<SPECIAL_794>",
801
+ "<SPECIAL_795>",
802
+ "<SPECIAL_796>",
803
+ "<SPECIAL_797>",
804
+ "<SPECIAL_798>",
805
+ "<SPECIAL_799>",
806
+ "<SPECIAL_800>",
807
+ "<SPECIAL_801>",
808
+ "<SPECIAL_802>",
809
+ "<SPECIAL_803>",
810
+ "<SPECIAL_804>",
811
+ "<SPECIAL_805>",
812
+ "<SPECIAL_806>",
813
+ "<SPECIAL_807>",
814
+ "<SPECIAL_808>",
815
+ "<SPECIAL_809>",
816
+ "<SPECIAL_810>",
817
+ "<SPECIAL_811>",
818
+ "<SPECIAL_812>",
819
+ "<SPECIAL_813>",
820
+ "<SPECIAL_814>",
821
+ "<SPECIAL_815>",
822
+ "<SPECIAL_816>",
823
+ "<SPECIAL_817>",
824
+ "<SPECIAL_818>",
825
+ "<SPECIAL_819>",
826
+ "<SPECIAL_820>",
827
+ "<SPECIAL_821>",
828
+ "<SPECIAL_822>",
829
+ "<SPECIAL_823>",
830
+ "<SPECIAL_824>",
831
+ "<SPECIAL_825>",
832
+ "<SPECIAL_826>",
833
+ "<SPECIAL_827>",
834
+ "<SPECIAL_828>",
835
+ "<SPECIAL_829>",
836
+ "<SPECIAL_830>",
837
+ "<SPECIAL_831>",
838
+ "<SPECIAL_832>",
839
+ "<SPECIAL_833>",
840
+ "<SPECIAL_834>",
841
+ "<SPECIAL_835>",
842
+ "<SPECIAL_836>",
843
+ "<SPECIAL_837>",
844
+ "<SPECIAL_838>",
845
+ "<SPECIAL_839>",
846
+ "<SPECIAL_840>",
847
+ "<SPECIAL_841>",
848
+ "<SPECIAL_842>",
849
+ "<SPECIAL_843>",
850
+ "<SPECIAL_844>",
851
+ "<SPECIAL_845>",
852
+ "<SPECIAL_846>",
853
+ "<SPECIAL_847>",
854
+ "<SPECIAL_848>",
855
+ "<SPECIAL_849>",
856
+ "<SPECIAL_850>",
857
+ "<SPECIAL_851>",
858
+ "<SPECIAL_852>",
859
+ "<SPECIAL_853>",
860
+ "<SPECIAL_854>",
861
+ "<SPECIAL_855>",
862
+ "<SPECIAL_856>",
863
+ "<SPECIAL_857>",
864
+ "<SPECIAL_858>",
865
+ "<SPECIAL_859>",
866
+ "<SPECIAL_860>",
867
+ "<SPECIAL_861>",
868
+ "<SPECIAL_862>",
869
+ "<SPECIAL_863>",
870
+ "<SPECIAL_864>",
871
+ "<SPECIAL_865>",
872
+ "<SPECIAL_866>",
873
+ "<SPECIAL_867>",
874
+ "<SPECIAL_868>",
875
+ "<SPECIAL_869>",
876
+ "<SPECIAL_870>",
877
+ "<SPECIAL_871>",
878
+ "<SPECIAL_872>",
879
+ "<SPECIAL_873>",
880
+ "<SPECIAL_874>",
881
+ "<SPECIAL_875>",
882
+ "<SPECIAL_876>",
883
+ "<SPECIAL_877>",
884
+ "<SPECIAL_878>",
885
+ "<SPECIAL_879>",
886
+ "<SPECIAL_880>",
887
+ "<SPECIAL_881>",
888
+ "<SPECIAL_882>",
889
+ "<SPECIAL_883>",
890
+ "<SPECIAL_884>",
891
+ "<SPECIAL_885>",
892
+ "<SPECIAL_886>",
893
+ "<SPECIAL_887>",
894
+ "<SPECIAL_888>",
895
+ "<SPECIAL_889>",
896
+ "<SPECIAL_890>",
897
+ "<SPECIAL_891>",
898
+ "<SPECIAL_892>",
899
+ "<SPECIAL_893>",
900
+ "<SPECIAL_894>",
901
+ "<SPECIAL_895>",
902
+ "<SPECIAL_896>",
903
+ "<SPECIAL_897>",
904
+ "<SPECIAL_898>",
905
+ "<SPECIAL_899>",
906
+ "<SPECIAL_900>",
907
+ "<SPECIAL_901>",
908
+ "<SPECIAL_902>",
909
+ "<SPECIAL_903>",
910
+ "<SPECIAL_904>",
911
+ "<SPECIAL_905>",
912
+ "<SPECIAL_906>",
913
+ "<SPECIAL_907>",
914
+ "<SPECIAL_908>",
915
+ "<SPECIAL_909>",
916
+ "<SPECIAL_910>",
917
+ "<SPECIAL_911>",
918
+ "<SPECIAL_912>",
919
+ "<SPECIAL_913>",
920
+ "<SPECIAL_914>",
921
+ "<SPECIAL_915>",
922
+ "<SPECIAL_916>",
923
+ "<SPECIAL_917>",
924
+ "<SPECIAL_918>",
925
+ "<SPECIAL_919>",
926
+ "<SPECIAL_920>",
927
+ "<SPECIAL_921>",
928
+ "<SPECIAL_922>",
929
+ "<SPECIAL_923>",
930
+ "<SPECIAL_924>",
931
+ "<SPECIAL_925>",
932
+ "<SPECIAL_926>",
933
+ "<SPECIAL_927>",
934
+ "<SPECIAL_928>",
935
+ "<SPECIAL_929>",
936
+ "<SPECIAL_930>",
937
+ "<SPECIAL_931>",
938
+ "<SPECIAL_932>",
939
+ "<SPECIAL_933>",
940
+ "<SPECIAL_934>",
941
+ "<SPECIAL_935>",
942
+ "<SPECIAL_936>",
943
+ "<SPECIAL_937>",
944
+ "<SPECIAL_938>",
945
+ "<SPECIAL_939>",
946
+ "<SPECIAL_940>",
947
+ "<SPECIAL_941>",
948
+ "<SPECIAL_942>",
949
+ "<SPECIAL_943>",
950
+ "<SPECIAL_944>",
951
+ "<SPECIAL_945>",
952
+ "<SPECIAL_946>",
953
+ "<SPECIAL_947>",
954
+ "<SPECIAL_948>",
955
+ "<SPECIAL_949>",
956
+ "<SPECIAL_950>",
957
+ "<SPECIAL_951>",
958
+ "<SPECIAL_952>",
959
+ "<SPECIAL_953>",
960
+ "<SPECIAL_954>",
961
+ "<SPECIAL_955>",
962
+ "<SPECIAL_956>",
963
+ "<SPECIAL_957>",
964
+ "<SPECIAL_958>",
965
+ "<SPECIAL_959>",
966
+ "<SPECIAL_960>",
967
+ "<SPECIAL_961>",
968
+ "<SPECIAL_962>",
969
+ "<SPECIAL_963>",
970
+ "<SPECIAL_964>",
971
+ "<SPECIAL_965>",
972
+ "<SPECIAL_966>",
973
+ "<SPECIAL_967>",
974
+ "<SPECIAL_968>",
975
+ "<SPECIAL_969>",
976
+ "<SPECIAL_970>",
977
+ "<SPECIAL_971>",
978
+ "<SPECIAL_972>",
979
+ "<SPECIAL_973>",
980
+ "<SPECIAL_974>",
981
+ "<SPECIAL_975>",
982
+ "<SPECIAL_976>",
983
+ "<SPECIAL_977>",
984
+ "<SPECIAL_978>",
985
+ "<SPECIAL_979>",
986
+ "<SPECIAL_980>",
987
+ "<SPECIAL_981>",
988
+ "<SPECIAL_982>",
989
+ "<SPECIAL_983>",
990
+ "<SPECIAL_984>",
991
+ "<SPECIAL_985>",
992
+ "<SPECIAL_986>",
993
+ "<SPECIAL_987>",
994
+ "<SPECIAL_988>",
995
+ "<SPECIAL_989>",
996
+ "<SPECIAL_990>",
997
+ "<SPECIAL_991>",
998
+ "<SPECIAL_992>",
999
+ "<SPECIAL_993>",
1000
+ "<SPECIAL_994>",
1001
+ "<SPECIAL_995>",
1002
+ "<SPECIAL_996>",
1003
+ "<SPECIAL_997>",
1004
+ "<SPECIAL_998>",
1005
+ "<SPECIAL_999>"
1006
+ ],
1007
+ "is_local": true,
1008
+ "model_max_length": 1000000000000000019884624838656,
1009
+ "pad_token": "<pad>",
1010
+ "processor_class": "PixtralProcessor",
1011
+ "tokenizer_class": "TokenizersBackend",
1012
+ "unk_token": "<unk>"
1013
+ }
vllm_patches.diff ADDED
@@ -0,0 +1,413 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ diff --git a/vllm/model_executor/layers/linear.py b/vllm/model_executor/layers/linear.py
2
+ index 5fc9fa073..ddb758886 100644
3
+ --- a/vllm/model_executor/layers/linear.py
4
+ +++ b/vllm/model_executor/layers/linear.py
5
+ @@ -257,13 +257,17 @@ class UnquantizedLinearMethod(LinearMethodBase):
6
+ x: torch.Tensor,
7
+ bias: torch.Tensor | None = None,
8
+ ) -> torch.Tensor:
9
+ + weight = layer.weight
10
+ + # Support FP8 weight storage: cast to compute dtype for GEMM
11
+ + if weight.dtype in (torch.float8_e4m3fn, torch.float8_e5m2):
12
+ + weight = weight.to(x.dtype)
13
+ if (
14
+ vllm_is_batch_invariant()
15
+ and current_platform.is_cuda_alike()
16
+ and is_layer_moe_router_gate(getattr(layer, "prefix", ""))
17
+ ):
18
+ - return linear_batch_invariant(x, layer.weight, bias)
19
+ - return dispatch_unquantized_gemm()(layer, x, layer.weight, bias)
20
+ + return linear_batch_invariant(x, weight, bias)
21
+ + return dispatch_unquantized_gemm()(layer, x, weight, bias)
22
+
23
+
24
+ class LinearBase(PluggableLayer):
25
+ diff --git a/vllm/model_executor/layers/quantization/modelopt.py b/vllm/model_executor/layers/quantization/modelopt.py
26
+ index 999bb6325..35db5468b 100644
27
+ --- a/vllm/model_executor/layers/quantization/modelopt.py
28
+ +++ b/vllm/model_executor/layers/quantization/modelopt.py
29
+ @@ -43,6 +43,10 @@ from vllm.model_executor.layers.linear import (
30
+ LinearMethodBase,
31
+ UnquantizedLinearMethod,
32
+ )
33
+ +from vllm.model_executor.layers.vocab_parallel_embedding import (
34
+ + ParallelLMHead,
35
+ + VocabParallelEmbedding,
36
+ +)
37
+ from vllm.model_executor.layers.quantization import QuantizationMethods
38
+ from vllm.model_executor.layers.quantization.base_config import (
39
+ QuantizationConfig,
40
+ @@ -190,6 +194,8 @@ class ModelOptQuantConfigBase(QuantizationConfig):
41
+ if self.is_layer_excluded(prefix):
42
+ if isinstance(layer, LinearBase):
43
+ return UnquantizedLinearMethod()
44
+ + if isinstance(layer, ParallelLMHead):
45
+ + return None # falls back to UnquantizedEmbeddingMethod
46
+ return None
47
+
48
+ # TODO: This special hard coded logic is not needed for quantized checkpoints
49
+ @@ -197,7 +203,7 @@ class ModelOptQuantConfigBase(QuantizationConfig):
50
+ # exclude_modules config. But need to keep them for loading quantized
51
+ # checkpoints generated by older versions. Then check substring matching
52
+ # for patterns not caught by exact match
53
+ - if "vision_tower" in prefix or "vision_model" in prefix:
54
+ + if "vision_tower" in prefix or "vision_model" in prefix or "visual" in prefix:
55
+ return UnquantizedLinearMethod()
56
+
57
+ # now, the layer is quantized, handle it here
58
+ @@ -213,6 +219,18 @@ class ModelOptQuantConfigBase(QuantizationConfig):
59
+ if getattr(quant_method, "backend", "") == "marlin":
60
+ quant_method.marlin_input_dtype = get_marlin_input_dtype(prefix)
61
+ return quant_method
62
+ + elif isinstance(layer, ParallelLMHead):
63
+ + # NVFP4-quantized lm_head: use LMHead-specific method that
64
+ + # handles VocabParallelEmbedding's weight_loader.
65
+ + quant_method = ModelOptNvFp4LMHeadMethod(self)
66
+ + if getattr(quant_method, "backend", "") == "marlin":
67
+ + quant_method.marlin_input_dtype = get_marlin_input_dtype(prefix)
68
+ + return quant_method
69
+ + elif isinstance(layer, VocabParallelEmbedding) and self.nvfp4_embed:
70
+ + # NVFP4-quantized embed_tokens: use custom embedding method
71
+ + # that does per-row dequantization during lookup.
72
+ + assert isinstance(self, ModelOptNvFp4Config)
73
+ + return ModelOptNvFp4EmbeddingMethod(self)
74
+
75
+ return None
76
+
77
+ @@ -1014,9 +1032,11 @@ class ModelOptNvFp4Config(ModelOptQuantConfigBase):
78
+ kv_cache_quant_algo: str | None,
79
+ exclude_modules: list[str],
80
+ group_size: int = 16,
81
+ + nvfp4_embed: bool = False,
82
+ ) -> None:
83
+ super().__init__(exclude_modules)
84
+ self.is_checkpoint_nvfp4_serialized = is_checkpoint_nvfp4_serialized
85
+ + self.nvfp4_embed = nvfp4_embed
86
+ if is_checkpoint_nvfp4_serialized:
87
+ logger.warning(
88
+ "Detected ModelOpt NVFP4 checkpoint. Please note that"
89
+ @@ -1075,11 +1095,22 @@ class ModelOptNvFp4Config(ModelOptQuantConfigBase):
90
+ f"hf_quant_config.json: {missing_fields}"
91
+ )
92
+
93
+ + nvfp4_embed = False
94
+ + if "quantization" in original_config:
95
+ + # hf_quant_config.json format: {"quantization": {"nvfp4_embed": true}}
96
+ + nvfp4_embed = original_config["quantization"].get(
97
+ + "nvfp4_embed", False
98
+ + )
99
+ + else:
100
+ + # compressed-tensors style format (config.json quantization_config)
101
+ + nvfp4_embed = original_config.get("nvfp4_embed", False)
102
+ +
103
+ return cls(
104
+ is_checkpoint_nvfp4_serialized,
105
+ kv_cache_quant_method,
106
+ exclude_modules,
107
+ group_size,
108
+ + nvfp4_embed,
109
+ )
110
+
111
+
112
+ @@ -1150,6 +1181,7 @@ class ModelOptNvFp4LinearMethod(LinearMethodBase):
113
+ data=torch.empty(len(output_partition_sizes), dtype=torch.float32),
114
+ weight_loader=weight_loader,
115
+ )
116
+ + input_global_scale[:] = torch.finfo(torch.float32).min
117
+ layer.register_parameter("input_scale", input_global_scale)
118
+
119
+ # Weight Global Scale
120
+ @@ -1157,6 +1189,7 @@ class ModelOptNvFp4LinearMethod(LinearMethodBase):
121
+ data=torch.empty(len(output_partition_sizes), dtype=torch.float32),
122
+ weight_loader=weight_loader,
123
+ )
124
+ + weight_global_scale[:] = torch.finfo(torch.float32).min
125
+ layer.register_parameter("weight_scale_2", weight_global_scale)
126
+
127
+ # Per Block Weight Scale
128
+ @@ -1207,6 +1240,245 @@ class ModelOptNvFp4LinearMethod(LinearMethodBase):
129
+ )
130
+
131
+
132
+ +class ModelOptNvFp4LMHeadMethod(ModelOptNvFp4LinearMethod):
133
+ + """NVFP4 method for ParallelLMHead (extends VocabParallelEmbedding).
134
+ +
135
+ + ParallelLMHead passes VocabParallelEmbedding.weight_loader to
136
+ + create_weights, but that loader doesn't handle NVFP4 packed uint8
137
+ + weights or PerTensorScaleParameter scalars. We override create_weights
138
+ + to supply a compatible weight_loader that handles vocab-parallel
139
+ + sharding for NVFP4 parameters.
140
+ + """
141
+ +
142
+ + def create_weights(
143
+ + self,
144
+ + layer: torch.nn.Module,
145
+ + input_size_per_partition: int,
146
+ + output_partition_sizes: list[int],
147
+ + input_size: int,
148
+ + output_size: int,
149
+ + params_dtype: torch.dtype,
150
+ + **extra_weight_attrs,
151
+ + ):
152
+ + # Build a weight_loader that works with NVFP4 packed parameters
153
+ + # on a VocabParallelEmbedding-based layer.
154
+ + embedding = layer # layer is the ParallelLMHead instance
155
+ +
156
+ + def _nvfp4_lm_head_weight_loader(
157
+ + param: torch.Tensor,
158
+ + loaded_weight: torch.Tensor,
159
+ + ):
160
+ + output_dim = getattr(param, "output_dim", None)
161
+ + if output_dim is None:
162
+ + # Scalar parameters (input_scale, weight_scale_2).
163
+ + # Checkpoint stores a scalar; parameter is 1-element tensor.
164
+ + if param.data.dim() == 1 and loaded_weight.dim() == 0:
165
+ + param.data[0] = loaded_weight.item()
166
+ + else:
167
+ + param.data.copy_(loaded_weight)
168
+ + return
169
+ +
170
+ + # Sharded parameters (weight, weight_scale): use the
171
+ + # VocabParallelEmbedding shard indices for the output dim.
172
+ + tp_size = embedding.tp_size
173
+ + if tp_size == 1:
174
+ + param.data.copy_(loaded_weight)
175
+ + else:
176
+ + start = embedding.shard_indices.org_vocab_start_index
177
+ + end = embedding.shard_indices.org_vocab_end_index
178
+ + shard_size = end - start
179
+ + input_dim = getattr(param, "input_dim", None)
180
+ + # Scale start/end by the packing ratio for packed dims
181
+ + if input_dim is not None and input_dim == output_dim:
182
+ + raise NotImplementedError(
183
+ + "Packed dim == output dim not supported for "
184
+ + "NVFP4 LM head"
185
+ + )
186
+ + loaded_weight = loaded_weight.narrow(
187
+ + output_dim, start, shard_size
188
+ + )
189
+ + param.data[: loaded_weight.shape[0]].copy_(loaded_weight)
190
+ + param.data[loaded_weight.shape[0] :].fill_(0)
191
+ +
192
+ + extra_weight_attrs["weight_loader"] = _nvfp4_lm_head_weight_loader
193
+ +
194
+ + # LinearBase sets params_dtype; VocabParallelEmbedding doesn't.
195
+ + # Marlin's prepare_fp4_layer_for_marlin needs it for scale dtype.
196
+ + if not hasattr(layer, "params_dtype"):
197
+ + layer.params_dtype = params_dtype
198
+ +
199
+ + super().create_weights(
200
+ + layer,
201
+ + input_size_per_partition,
202
+ + output_partition_sizes,
203
+ + input_size,
204
+ + output_size,
205
+ + params_dtype,
206
+ + **extra_weight_attrs,
207
+ + )
208
+ +
209
+ +
210
+ +class ModelOptNvFp4EmbeddingMethod(QuantizeMethodBase):
211
+ + """NVFP4 method for VocabParallelEmbedding (embed_tokens).
212
+ +
213
+ + Stores embedding weights in NVFP4 packed format to save VRAM
214
+ + (320 MB vs 1280 MB for BF16 with 131072×5120 embeddings).
215
+ + Dequantizes per-row during lookup.
216
+ + """
217
+ +
218
+ + # FP4 E2M1 lookup table: maps 4-bit index to float value
219
+ + FP4_E2M1_LUT = [
220
+ + 0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0,
221
+ + 0.0, -0.5, -1.0, -1.5, -2.0, -3.0, -4.0, -6.0,
222
+ + ]
223
+ +
224
+ + def __init__(self, quant_config: "ModelOptNvFp4Config") -> None:
225
+ + self.quant_config = quant_config
226
+ +
227
+ + def create_weights(
228
+ + self,
229
+ + layer: torch.nn.Module,
230
+ + input_size_per_partition: int,
231
+ + output_partition_sizes: list[int],
232
+ + input_size: int,
233
+ + output_size: int,
234
+ + params_dtype: torch.dtype,
235
+ + **extra_weight_attrs,
236
+ + ):
237
+ + embedding = layer # layer is the VocabParallelEmbedding instance
238
+ + output_size_per_partition = sum(output_partition_sizes)
239
+ + group_size = self.quant_config.group_size
240
+ +
241
+ + def _nvfp4_embed_weight_loader(
242
+ + param: torch.Tensor,
243
+ + loaded_weight: torch.Tensor,
244
+ + ):
245
+ + output_dim = getattr(param, "output_dim", None)
246
+ + if output_dim is None:
247
+ + # Scalar parameters (input_scale, weight_scale_2)
248
+ + if param.data.dim() == 1 and loaded_weight.dim() == 0:
249
+ + param.data[0] = loaded_weight.item()
250
+ + else:
251
+ + param.data.copy_(loaded_weight)
252
+ + return
253
+ +
254
+ + tp_size = embedding.tp_size
255
+ + if tp_size == 1:
256
+ + param.data.copy_(loaded_weight)
257
+ + else:
258
+ + start = embedding.shard_indices.org_vocab_start_index
259
+ + end = embedding.shard_indices.org_vocab_end_index
260
+ + shard_size = end - start
261
+ + loaded_weight = loaded_weight.narrow(
262
+ + output_dim, start, shard_size
263
+ + )
264
+ + param.data[: loaded_weight.shape[0]].copy_(loaded_weight)
265
+ + param.data[loaded_weight.shape[0] :].fill_(0)
266
+ +
267
+ + # Packed NVFP4 weight: [vocab, hidden/2] uint8
268
+ + from vllm.model_executor.parameter import ModelWeightParameter
269
+ + weight = ModelWeightParameter(
270
+ + data=torch.empty(
271
+ + output_size_per_partition,
272
+ + input_size_per_partition // 2,
273
+ + dtype=torch.uint8,
274
+ + ),
275
+ + input_dim=1,
276
+ + output_dim=0,
277
+ + weight_loader=_nvfp4_embed_weight_loader,
278
+ + )
279
+ + layer.register_parameter("weight", weight)
280
+ +
281
+ + # Per-group scale: [vocab, hidden/group_size] float8_e4m3fn
282
+ + weight_scale = ModelWeightParameter(
283
+ + data=torch.empty(
284
+ + output_size_per_partition,
285
+ + input_size_per_partition // group_size,
286
+ + dtype=torch.float8_e4m3fn,
287
+ + ),
288
+ + input_dim=1,
289
+ + output_dim=0,
290
+ + weight_loader=_nvfp4_embed_weight_loader,
291
+ + )
292
+ + layer.register_parameter("weight_scale", weight_scale)
293
+ +
294
+ + # Global scales (scalars)
295
+ + from vllm.model_executor.parameter import PerTensorScaleParameter
296
+ + input_scale = PerTensorScaleParameter(
297
+ + data=torch.empty(1, dtype=torch.float32),
298
+ + weight_loader=_nvfp4_embed_weight_loader,
299
+ + )
300
+ + layer.register_parameter("input_scale", input_scale)
301
+ +
302
+ + weight_scale_2 = PerTensorScaleParameter(
303
+ + data=torch.empty(1, dtype=torch.float32),
304
+ + weight_loader=_nvfp4_embed_weight_loader,
305
+ + )
306
+ + layer.register_parameter("weight_scale_2", weight_scale_2)
307
+ +
308
+ + def process_weights_after_loading(self, layer: torch.nn.Module) -> None:
309
+ + # Merge global scales into a single alpha factor
310
+ + input_gs = layer.input_scale.max().to(torch.float32)
311
+ + weight_gs = layer.weight_scale_2.max().to(torch.float32)
312
+ + layer.global_scale = Parameter(
313
+ + input_gs * weight_gs, requires_grad=False
314
+ + )
315
+ + del layer.input_scale, layer.weight_scale_2
316
+ +
317
+ + # Build FP4 E2M1 lookup table on the correct device
318
+ + layer.fp4_lut = torch.tensor(
319
+ + self.FP4_E2M1_LUT, dtype=torch.bfloat16,
320
+ + device=layer.weight.device,
321
+ + )
322
+ +
323
+ + def embedding(
324
+ + self, layer: torch.nn.Module, input_: torch.Tensor,
325
+ + ) -> torch.Tensor:
326
+ + """NVFP4 embedding lookup with per-row dequantization."""
327
+ + group_size = self.quant_config.group_size
328
+ + packed = layer.weight # [vocab, hidden/2] uint8
329
+ + scales = layer.weight_scale # [vocab, hidden/group_size] fp8
330
+ + global_scale = layer.global_scale # scalar
331
+ + fp4_lut = layer.fp4_lut # [16] bf16
332
+ +
333
+ + # 1. Index into packed arrays by token IDs
334
+ + ids = input_.long()
335
+ + packed_rows = packed[ids] # [..., hidden/2] uint8
336
+ + scale_rows = scales[ids] # [..., hidden/group_size] fp8
337
+ +
338
+ + # 2. Unpack uint8 → two FP4 indices (low nibble first)
339
+ + low = (packed_rows & 0x0F).long() # [..., hidden/2]
340
+ + high = (packed_rows >> 4).long() # [..., hidden/2]
341
+ + # Interleave: element 2i = low[i], element 2i+1 = high[i]
342
+ + unpacked = torch.stack([low, high], dim=-1) # [..., hidden/2, 2]
343
+ + orig_shape = list(ids.shape) + [packed.shape[-1] * 2]
344
+ + unpacked = unpacked.reshape(orig_shape) # [..., hidden]
345
+ +
346
+ + # 3. FP4 → float via lookup table
347
+ + dequant = fp4_lut[unpacked] # [..., hidden] bf16
348
+ +
349
+ + # 4. Apply per-group scale and global scale
350
+ + scale_rows_bf16 = scale_rows.to(torch.bfloat16) # [..., hidden/gs]
351
+ + scale_rows_expanded = scale_rows_bf16.repeat_interleave(
352
+ + group_size, dim=-1
353
+ + ) # [..., hidden]
354
+ + dequant = dequant * scale_rows_expanded * global_scale.to(
355
+ + torch.bfloat16
356
+ + )
357
+ +
358
+ + return dequant
359
+ +
360
+ + def apply(
361
+ + self,
362
+ + layer: torch.nn.Module,
363
+ + x: torch.Tensor,
364
+ + bias: torch.Tensor | None = None,
365
+ + ) -> torch.Tensor:
366
+ + raise NotImplementedError(
367
+ + "NVFP4 embedding does not support linear apply"
368
+ + )
369
+ +
370
+ +
371
+ class ModelOptNvFp4FusedMoE(FusedMoEMethodBase):
372
+ """
373
+ MoE Method for FP4 Quantization.
374
+ diff --git a/vllm/model_executor/layers/vocab_parallel_embedding.py b/vllm/model_executor/layers/vocab_parallel_embedding.py
375
+ index daaa86bed..ac5bedb6b 100644
376
+ --- a/vllm/model_executor/layers/vocab_parallel_embedding.py
377
+ +++ b/vllm/model_executor/layers/vocab_parallel_embedding.py
378
+ @@ -66,10 +66,18 @@ class UnquantizedEmbeddingMethod(QuantizeMethodBase):
379
+ x: torch.Tensor,
380
+ bias: torch.Tensor | None = None,
381
+ ) -> torch.Tensor:
382
+ - return dispatch_unquantized_gemm()(layer, x, layer.weight, bias)
383
+ + weight = layer.weight
384
+ + # Support FP8 weight storage: cast to compute dtype for GEMM
385
+ + if weight.dtype in (torch.float8_e4m3fn, torch.float8_e5m2):
386
+ + weight = weight.to(x.dtype)
387
+ + return dispatch_unquantized_gemm()(layer, x, weight, bias)
388
+
389
+ def embedding(self, layer: torch.nn.Module, input_: torch.Tensor) -> torch.Tensor:
390
+ - return F.embedding(input_, layer.weight)
391
+ + output = F.embedding(input_, layer.weight)
392
+ + # Support FP8 weight storage: cast to compute dtype after lookup
393
+ + if output.dtype in (torch.float8_e4m3fn, torch.float8_e5m2):
394
+ + output = output.to(torch.bfloat16)
395
+ + return output
396
+
397
+
398
+ def pad_vocab_size(vocab_size: int, pad_to: int = DEFAULT_VOCAB_PADDING_SIZE) -> int:
399
+ @@ -429,6 +437,14 @@ class VocabParallelEmbedding(CustomOp):
400
+ shape[output_dim] = self.num_embeddings_per_partition
401
+ param.materialize(tuple(shape), dtype=loaded_weight.dtype)
402
+
403
+ + # If loaded weight is FP8, cast parameter to match so FP8 is
404
+ + # preserved in memory (saves VRAM for e.g. embed_tokens).
405
+ + if loaded_weight.dtype in (torch.float8_e4m3fn,
406
+ + torch.float8_e5m2):
407
+ + if param.data.dtype != loaded_weight.dtype:
408
+ + param.data = torch.empty_like(param.data,
409
+ + dtype=loaded_weight.dtype)
410
+ +
411
+ # If parameter does not have output dim, then it should
412
+ # be copied onto all gpus (e.g. g_idx for act_order gptq).
413
+ if output_dim is None: