demon-zombie commited on
Commit
bacdce3
·
verified ·
1 Parent(s): 5e50c1e

Add vLLM NVFP4 lm_head patch (ParallelLMHead -> ReplicatedLinear)

Browse files
Files changed (1) hide show
  1. vllm-patches/patch_nvfp4_lm_head.py +69 -0
vllm-patches/patch_nvfp4_lm_head.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Patch vLLM's qwen3_5.py to support NVFP4-quantized lm_head.
3
+
4
+ Problem: vLLM's ParallelLMHead inherits from VocabParallelEmbedding, which
5
+ doesn't support quantized weight loading (NVFP4 packed format). The
6
+ compressed-tensors quantization method can't match "Linear" target to
7
+ "ParallelLMHead" class name, and even if it could, VocabParallelEmbedding's
8
+ weight_loader doesn't handle packed weights.
9
+
10
+ Fix: Replace ParallelLMHead with ReplicatedLinear for lm_head, which goes
11
+ through the standard quantized linear weight loading path. Also hardcode
12
+ hidden_size=3072 because the inner CausalLM class sees text_config defaults
13
+ (2048) instead of the actual model hidden_size.
14
+
15
+ Usage (inside container):
16
+ python3 /workspace/patch_nvfp4_lm_head.py
17
+
18
+ Or from host:
19
+ docker cp patch_nvfp4_lm_head.py CONTAINER:/tmp/
20
+ docker exec CONTAINER python3 /tmp/patch_nvfp4_lm_head.py
21
+ docker restart CONTAINER
22
+ """
23
+
24
+ import sys
25
+
26
+ TARGET = "/usr/local/lib/python3.12/dist-packages/vllm/model_executor/models/qwen3_5.py"
27
+
28
+ with open(TARGET) as f:
29
+ content = f.read()
30
+
31
+ changes = 0
32
+
33
+ # 1. Add ReplicatedLinear import
34
+ old_import = "from vllm.model_executor.layers.vocab_parallel_embedding import ("
35
+ new_import = "from vllm.model_executor.layers.linear import ReplicatedLinear\nfrom vllm.model_executor.layers.vocab_parallel_embedding import ("
36
+ if old_import in content and "ReplicatedLinear" not in content:
37
+ content = content.replace(old_import, new_import, 1)
38
+ changes += 1
39
+ print("[1/2] Added ReplicatedLinear import")
40
+
41
+ # 2. Replace ParallelLMHead with ReplicatedLinear for lm_head
42
+ old_lm = """ self.lm_head = ParallelLMHead(
43
+ config.vocab_size,
44
+ config.hidden_size,
45
+ prefix=maybe_prefix(prefix, "lm_head"),
46
+ )"""
47
+
48
+ new_lm = """ self.lm_head = ReplicatedLinear(
49
+ 3072,
50
+ config.vocab_size,
51
+ bias=False,
52
+ quant_config=self.quant_config,
53
+ prefix=maybe_prefix(prefix, "lm_head"),
54
+ )"""
55
+
56
+ if old_lm in content:
57
+ content = content.replace(old_lm, new_lm)
58
+ changes += 1
59
+ print("[2/2] Replaced ParallelLMHead with ReplicatedLinear(3072, vocab_size)")
60
+
61
+ if changes == 0:
62
+ print("ERROR: No patterns matched. File may already be patched or version mismatch.")
63
+ sys.exit(1)
64
+
65
+ with open(TARGET, "w") as f:
66
+ f.write(content)
67
+
68
+ print(f"\nPatched {TARGET} ({changes} changes)")
69
+ print("Restart the container to apply.")