Views
No views yet
Linear layers or are highly sensitive to quantization error.
Quantization is performed using the NVFP4 scheme (QuantizationModifier), which targets NVIDIA H100 and Blackwell (sm90+) GPUs, with calibration performed over 256 samples from HuggingFaceH4/ultrachat_200k and moe_calibrate_all_experts=True so that every one of the 256 experts per layer receives calibration signal, not just the experts that are routed to for the sampled tokens.
The llm-compressor library is used for quantization.1from vllm import LLM, SamplingParams
2from transformers import AutoTokenizer
3
4model_id = "RedHatAI/Ornith-1.0-35B-NVFP4"
5number_gpus = 1
6sampling_params = SamplingParams(temperature=0.6, top_p=0.95, top_k=20, min_p=0, max_tokens=256)
7
8tokenizer = AutoTokenizer.from_pretrained(model_id)
9messages = [{"role": "user", "content": "Give me a short introduction to large language model."}]
10prompts = tokenizer.apply_chat_template(messages, add_generation_prompt=True, tokenize=False)
11
12llm = LLM(model=model_id, tensor_parallel_size=number_gpus)
13outputs = llm.generate(prompts, sampling_params)
14generated_text = outputs[0].outputs[0].text
15print(generated_text)oneshot recipe used upstream for Qwen/Qwen3.5-122B-A10B (the reference example for the Qwen3_5MoeForConditionalGeneration architecture that Ornith-1.0-35B shares), pointed at deepreinforce-ai/Ornith-1.0-35B. Note: unlike Qwen/Qwen3.5-*, the deepreinforce-ai/Ornith-1.0-35B checkpoint does not ship separate MTP (multi-token-prediction) tensors, so the save_mtp_tensors_to_checkpoint step used upstream is omitted here.1import torch
2from datasets import load_dataset
3from transformers import AutoProcessor, Qwen3_5MoeForConditionalGeneration
4
5from llmcompressor import oneshot
6from llmcompressor.modifiers.quantization import QuantizationModifier
7from llmcompressor.utils import load_context
8
9# NOTE: This example requires transformers >= v5
10
11MODEL_ID = "deepreinforce-ai/Ornith-1.0-35B"
12
13# Load model.
14with load_context(Qwen3_5MoeForConditionalGeneration):
15 model = Qwen3_5MoeForConditionalGeneration.from_pretrained(MODEL_ID)
16processor = AutoProcessor.from_pretrained(MODEL_ID)
17
18recipe = QuantizationModifier(
19 targets="Linear",
20 scheme="NVFP4",
21 ignore=[
22 "re:.*lm_head",
23 "re:visual.*",
24 "re:model.visual.*",
25 "re:.*mlp.gate$",
26 "re:.*embed_tokens$",
27 "re:.*shared_expert_gate$",
28 "re:.*linear_attn.*",
29 ],
30)
31
32NUM_CALIBRATION_SAMPLES = 256
33MAX_SEQUENCE_LENGTH = 4096
34
35ds = load_dataset(
36 "HuggingFaceH4/ultrachat_200k",
37 split=f"train_sft[:{NUM_CALIBRATION_SAMPLES}]",
38)
39ds = ds.select_columns(["messages"])
40ds = ds.shuffle(seed=42)
41
42
43def preprocess_function(example):
44 messages = [
45 {"role": m["role"], "content": [{"type": "text", "text": m["content"]}]}
46 for m in example["messages"]
47 ]
48 return processor.apply_chat_template(
49 messages,
50 return_tensors="pt",
51 padding=False,
52 truncation=True,
53 max_length=MAX_SEQUENCE_LENGTH,
54 tokenize=True,
55 add_special_tokens=False,
56 return_dict=True,
57 add_generation_prompt=False,
58 )
59
60
61ds = ds.map(preprocess_function, batched=False, remove_columns=ds.column_names)
62
63
64def data_collator(batch):
65 assert len(batch) == 1
66 return {key: torch.tensor(value) for key, value in batch[0].items()}
67
68
69# Apply quantization.
70oneshot(
71 model=model,
72 recipe=recipe,
73 dataset=ds,
74 max_seq_length=MAX_SEQUENCE_LENGTH,
75 num_calibration_samples=NUM_CALIBRATION_SAMPLES,
76 moe_calibrate_all_experts=True,
77 data_collator=data_collator,
78)
79
80# Save to disk in compressed-tensors format.
81SAVE_DIR = MODEL_ID.rstrip("/").split("/")[-1] + "-NVFP4"
82model.save_pretrained(SAVE_DIR)
83processor.save_pretrained(SAVE_DIR)