ig1sa commited on
Commit
ab67df4
·
verified ·
1 Parent(s): 18825c5

Add files using upload-large-folder tool

Browse files
Files changed (1) hide show
  1. Qwen3.5-122B-A10B_nvfp4.py +167 -0
Qwen3.5-122B-A10B_nvfp4.py ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datasets import load_dataset, concatenate_datasets
2
+ from transformers import AutoTokenizer, Qwen3_5MoeForConditionalGeneration
3
+
4
+ from llmcompressor import oneshot
5
+ from llmcompressor.modifiers.quantization import QuantizationModifier
6
+
7
+ # NOTE: This example requires transformers >= v5
8
+
9
+ MODEL_ID = "Qwen/Qwen3.5-122B-A10B"
10
+
11
+ # Load model.
12
+ model = Qwen3_5MoeForConditionalGeneration.from_pretrained(MODEL_ID, dtype="auto")
13
+ processor = AutoTokenizer.from_pretrained(MODEL_ID)
14
+
15
+ recipe = QuantizationModifier(
16
+ targets="Linear",
17
+ scheme="NVFP4",
18
+ ignore=[
19
+ "re:.*lm_head",
20
+ "re:visual.*",
21
+ "re:model.visual.*",
22
+ "re:.*mlp.gate$",
23
+ "re:.*embed_tokens$",
24
+ "re:.*shared_expert_gate$",
25
+ "re:.*linear_attn.*",
26
+ ]
27
+ )
28
+
29
+ NUM_CALIBRATION_SAMPLES = 1024
30
+ MAX_SEQUENCE_LENGTH = 8192
31
+ samples_per_split = NUM_CALIBRATION_SAMPLES // 4 # 256 per domain
32
+
33
+ # ============================================================
34
+ # 1. General conversation (English)
35
+ # ============================================================
36
+ ds_chat = load_dataset(
37
+ "HuggingFaceH4/ultrachat_200k",
38
+ split=f"train_sft[:{samples_per_split}]",
39
+ )
40
+
41
+
42
+ def preprocess_chat(example):
43
+ text = processor.apply_chat_template(
44
+ example["messages"], tokenize=False
45
+ )
46
+ return {"text": text}
47
+
48
+
49
+ ds_chat = ds_chat.map(preprocess_chat).select_columns(["text"])
50
+
51
+ # ============================================================
52
+ # 2. Math / reasoning
53
+ # ============================================================
54
+ ds_math = load_dataset(
55
+ "openai/gsm8k", "main",
56
+ split=f"train[:{samples_per_split}]",
57
+ )
58
+
59
+
60
+ def preprocess_math(example):
61
+ messages = [
62
+ {"role": "user", "content": example["question"]},
63
+ {"role": "assistant", "content": example["answer"]},
64
+ ]
65
+ text = processor.apply_chat_template(messages, tokenize=False)
66
+ return {"text": text}
67
+
68
+
69
+ ds_math = ds_math.map(preprocess_math).select_columns(["text"])
70
+
71
+ # ============================================================
72
+ # 3. Code
73
+ # ============================================================
74
+ ds_code = load_dataset(
75
+ "sahil2801/CodeAlpaca-20k",
76
+ split=f"train[:{samples_per_split}]",
77
+ )
78
+
79
+
80
+ def preprocess_code(example):
81
+ user_content = example["instruction"]
82
+ if example.get("input"):
83
+ user_content += "\n\n" + example["input"]
84
+ messages = [
85
+ {"role": "user", "content": user_content},
86
+ {"role": "assistant", "content": example["output"]},
87
+ ]
88
+ text = processor.apply_chat_template(messages, tokenize=False)
89
+ return {"text": text}
90
+
91
+
92
+ ds_code = ds_code.map(preprocess_code).select_columns(["text"])
93
+
94
+ # ============================================================
95
+ # 4. Multilingual
96
+ # ============================================================
97
+ ds_multi = load_dataset(
98
+ "CohereForAI/aya_dataset",
99
+ split=f"train[:{samples_per_split}]",
100
+ )
101
+
102
+
103
+ def preprocess_multi(example):
104
+ messages = [
105
+ {"role": "user", "content": example["inputs"]},
106
+ {"role": "assistant", "content": example["targets"]},
107
+ ]
108
+ text = processor.apply_chat_template(messages, tokenize=False)
109
+ return {"text": text}
110
+
111
+
112
+ ds_multi = ds_multi.map(preprocess_multi).select_columns(["text"])
113
+
114
+ # ============================================================
115
+ # Combine all datasets and shuffle
116
+ # ============================================================
117
+ ds = concatenate_datasets([ds_chat, ds_math, ds_code, ds_multi])
118
+ ds = ds.shuffle(seed=42)
119
+
120
+ # Filter out any empty entries just in case.
121
+ ds = ds.filter(lambda x: len(x["text"].strip()) > 0)
122
+
123
+
124
+ # Tokenize inputs.
125
+ def tokenize(sample):
126
+ return processor(
127
+ sample["text"],
128
+ padding=False,
129
+ max_length=MAX_SEQUENCE_LENGTH,
130
+ truncation=True,
131
+ add_special_tokens=False,
132
+ )
133
+
134
+
135
+ ds = ds.map(tokenize, remove_columns=ds.column_names)
136
+
137
+
138
+ # ============================================================
139
+ # Patch: llmcompressor reads attention config from top-level,
140
+ # but for this multimodal model it lives in text_config
141
+ # ============================================================
142
+ text_cfg = model.config.text_config
143
+
144
+ for attr in [
145
+ "num_attention_heads",
146
+ "num_key_value_heads",
147
+ "hidden_size",
148
+ "head_dim",
149
+ ]:
150
+ if not hasattr(model.config, attr) and hasattr(text_cfg, attr):
151
+ setattr(model.config, attr, getattr(text_cfg, attr))
152
+
153
+
154
+ # Apply quantization.
155
+ oneshot(
156
+ model=model,
157
+ recipe=recipe,
158
+ dataset=ds,
159
+ max_seq_length=MAX_SEQUENCE_LENGTH,
160
+ num_calibration_samples=NUM_CALIBRATION_SAMPLES,
161
+ moe_calibrate_all_experts=True,
162
+ )
163
+
164
+ # Save to disk in compressed-tensors format.
165
+ SAVE_DIR = MODEL_ID.rstrip("/").split("/")[-1] + "-NVFP4"
166
+ model.save_pretrained(SAVE_DIR, safe_serialization=True)
167
+ processor.save_pretrained(SAVE_DIR)