catplusplus/Qwen3.5-122B-A10B-heretic-v2-NVFP4

认证创作者 catplusplus 已认证
🤗 Hugging Face 来源apache-2.071.2B 参数激活 10B76 GBsafetensors✓ 4 个校验和今天更新
一条命令提交

在你的模型文件夹旁边运行它。它会制作种子、将文件与 Hugging Face 比对,然后提交。你只需开始做种,并粘贴你账户中的密钥。它只读取你的文件,绝不修改。如果愿意,可以先阅读脚本。

curl -fsSL https://pirateface.co/package.sh | bash -s -- --repo catplusplus/Qwen3.5-122B-A10B-heretic-v2-NVFP4 ./model-folder
需要做种者 →

The model was converted to nvfp4 using llmcompressor and script below on a dual H200 runpod instance. It can generate outputs unsuitable for all audiences.

import os import sys import shutil

from datasets import concatenate_datasets, load_dataset from huggingface_hub import snapshot_download from transformers import AutoModelForImageTextToText, AutoTokenizer

from llmcompressor import oneshot from llmcompressor.modifiers.quantization import QuantizationModifier from llmcompressor.utils import dispatch_for_generation

Available Qwen3.5 MoE models (pick one):

"Qwen/Qwen3.5-35B-A3B"

"Qwen/Qwen3.5-122B-A10B"

"Qwen/Qwen3.5-397B-A17B"

#MODEL_ID = "Qwen/Qwen3.5-35B-A3B" MODEL_ID = sys.argv[1]

Load model.

model = AutoModelForImageTextToText.from_pretrained(MODEL_ID, dtype="auto") tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)

Select number of samples. 512 is recommended for production quality;

reduce to 256 or lower for faster iteration during development.

NUM_CALIBRATION_SAMPLES = 256 MAX_SEQUENCE_LENGTH = 4096

Load datasets and preprocess.

Use half from each source for a diverse calibration set.

samples_per_dataset = NUM_CALIBRATION_SAMPLES // 2

ds_ultrachat = load_dataset( "HuggingFaceH4/ultrachat_200k", split=f"train_sft[:{samples_per_dataset}]", ) ds_nemotron = load_dataset( "nvidia/Nemotron-Post-Training-Dataset-v2", split=f"chat[:{samples_per_dataset}]", )

Both datasets share a "messages" column with the same chat format.

Keep only that column so we can concatenate them.

ds_ultrachat = ds_ultrachat.select_columns(["messages"]) ds_nemotron = ds_nemotron.select_columns(["messages"]) ds = concatenate_datasets([ds_ultrachat, ds_nemotron]) ds = ds.shuffle(seed=42)

def preprocess(example): return { "text": tokenizer.apply_chat_template( example["messages"], tokenize=False, ) }

ds = ds.map(preprocess)

Tokenize inputs.

def tokenize(sample): return tokenizer( sample["text"], padding=False, max_length=MAX_SEQUENCE_LENGTH, truncation=True, add_special_tokens=False, )

ds = ds.map(tokenize, remove_columns=ds.column_names)

Configure the quantization algorithm and scheme.

In this case, we:

* quantize the weights to fp4 with per group 16 via ptq

* calibrate a global_scale for activations, which will be used to

quantize activations to fp4 on the fly

recipe = QuantizationModifier( targets="Linear", scheme="NVFP4", ignore=[ "lm_head", "re:.*mlp.gate$", "re:.mlp.shared_expert_gate$", "re:.linear_attn.", "re:model\.visual\..", ], )

Apply quantization.

MoE calibration is now handled automatically by the pipeline.

We set moe_calibrate_all_experts to True to ensure all experts receive

calibration data. This temporarily updates the model definition to use

CalibrationQwen3_5MoeSparseMoeBlock (from llmcompressor.modeling.qwen3_5_moe)

which replaces the original Qwen3_5MoeSparseMoeBlock class.

This unfuses the 3D expert parameters into individual nn.Linear modules

so they can be targeted by quantization.

Feel free to update the definition under

llm-compressor/src/llmcompressor/modeling/qwen3_5_moe.py to play around with

this behavior and evaluate its impact on quantization performance.

oneshot( model=model, dataset=ds, recipe=recipe, max_seq_length=MAX_SEQUENCE_LENGTH, num_calibration_samples=NUM_CALIBRATION_SAMPLES, moe_calibrate_all_experts=True, )

print("\n\n") print("========== SAMPLE GENERATION ==============") try: dispatch_for_generation(model) input_ids = tokenizer("Hello my name is", return_tensors="pt").input_ids.to( model.device ) output = model.generate(input_ids, max_new_tokens=100) print(tokenizer.decode(output[0])) except Exception as e: print(f"Generation failed (non-fatal): {e}") print("==========================================\n\n")

Save to disk in compressed-tensors format.

MTP (multi-token prediction) weights are automatically preserved from

the source checkpoint during save, enabling speculative decoding with vLLM.

SAVE_DIR = MODEL_ID.rstrip("/").split("/")[-1] + "-NVFP4" model.save_pretrained(SAVE_DIR, save_compressed=True) tokenizer.save_pretrained(SAVE_DIR)

Hot-fix: copy processor configs that save_pretrained doesn't bring over

cache_dir = snapshot_download(MODEL_ID, allow_patterns=["*.json"]) for filename in [ "preprocessor_config.json", "video_preprocessor_config.json", ]: src = os.path.join(cache_dir, filename) if os.path.exists(src): shutil.copyfile(src, os.path.join(SAVE_DIR, filename))