使用llm-compressor 对 Qwen3-14B 做 AWQ + INT4 量化

一、环境准备

1. 创建与激活 Conda 环境

bash 复制代码
conda create -n qwen3-awq python=3.10 -y
conda activate qwen3-awq

2. 安装 PyTorch(带 CUDA)

注意:下面的 CUDA 版本 cu129 要和机器上的 CUDA/驱动匹配。

bash 复制代码
pip install --upgrade pip

pip install torch==2.9.0 torchvision torchaudio \
  --extra-index-url https://download.pytorch.org/whl/cu129

3. 安装 llmcompressor、vLLM 和相关依赖

bash 复制代码
pip install "vllm>=0.6.0" "llmcompressor>=0.8.0"
pip install "transformers>=4.44.0" "accelerate" "datasets" "safetensors" "huggingface_hub"
pip install "bitsandbytes"

二、确认 GPU 是否可用

在 Python 里执行:

python 复制代码
import torch
print("cuda:", torch.cuda.is_available(), "device:", torch.cuda.get_device_name(0))

如果输出类似:

bash 复制代码
cuda: True device: NVIDIA A100-SXM-80GB

说明 GPU 可以正常使用。

三、编写量化脚本(AWQ + INT4)

下面给出一个完整可运行脚本,保存为 awq_int4_qwen3.py 之类的名字即可。

该脚本主要实现以下功能:

  1. 加载 Qwen3-14B 原始模型和分词器

  2. 加载校准数据集 ultrachat_200k

  3. 配置 AWQ 的 INT4 量化(W4A16)

  4. 调用 oneshot 完成量化

  5. 简单生成一段文本测试

  6. 将量化后模型保存到本地

python 复制代码
import os

# 可选:使用 HuggingFace 镜像(例如中国大陆环境)
os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"

from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer

from llmcompressor import oneshot
from llmcompressor.modifiers.awq import AWQModifier

# ======================
# 1. 模型路径配置
# ======================
# 如果你是本地已经下好的模型,保持文档中的写法,例如:
MODEL_ID = "/mnt/e/models/Qwen3-14B-2"
# 如果是从 HuggingFace 在线拉取,可以写成:
# MODEL_ID = "Qwen/Qwen2-7B-Instruct"  # 仅示例,换成真正的 Qwen3-14B 路径

# ======================
# 2. 加载模型和分词器
# ======================
print(f"Loading model from {MODEL_ID} ...")
model = AutoModelForCausalLM.from_pretrained(
    MODEL_ID,
    dtype="auto",        # 自动选择精度,一般是 bfloat16 / float16
    device_map="auto",   # 自动将模型切到 GPU / 多卡
    offload_folder="offload"  # 注意:这里参数名是 offload_folder
)

tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, trust_remote_code=True)

# ======================
# 3. 准备校准数据集
# ======================
# 使用 ultrachat_200k 的 train_sft split
DATASET_ID = "HuggingFaceH4/ultrachat_200k"
DATASET_SPLIT = "train_sft"

# 采样 256 条做校准(可以适当增加,精度会更好但更耗时)
NUM_CALIBRATION_SAMPLES = 256
MAX_SEQUENCE_LENGTH = 512

print("Loading calibration dataset...")
ds = load_dataset(
    DATASET_ID,
    split=f"{DATASET_SPLIT}[:{NUM_CALIBRATION_SAMPLES}]"
)
ds = ds.shuffle(seed=42)

# 将聊天数据转成纯文本,使用 chat_template
def preprocess(example):
    return {
        "text": tokenizer.apply_chat_template(
            example["messages"],
            tokenize=False,
        )
    }

ds = ds.map(preprocess)

# 如需显式 tokenization,可以再执行一次 map:
def tokenize(sample):
    return tokenizer(
        sample["text"],
        padding=False,
        max_length=MAX_SEQUENCE_LENGTH,
        truncation=True,
        add_special_tokens=False,
    )

# 可选:如果你希望在 oneshot 前就把 input_ids 准备好,可以取消下面注释
# ds = ds.map(tokenize, remove_columns=ds.column_names)

# ======================
# 4. 配置 AWQ INT4 量化
# ======================
# 说明:
#   - ignore:跳过 lm_head 以及一些 MoE 门控层不做量化
#   - scheme:这里是重点!INT4 用 W4A16
#   - targets:只量化 Linear 层
#   - group_size:分组量化的组大小,128 是个常用设置
recipe = [
    AWQModifier(
        ignore=["lm_head", "re:.*mlp.gate$", "re:.*mlp.shared_expert_gate$"],
        scheme="W4A16",          # ✅ INT4 量化:W4A16(文档注释:INT4量化用W4A16)
        targets=["Linear"],
        group_size=128,
    ),
]

# ======================
# 5. 运行 oneshot 量化
# ======================
if __name__ == "__main__":
    print("Start AWQ INT4 quantization ...")
    oneshot(
        model=model,
        dataset=ds,
        recipe=recipe,
        max_seq_length=MAX_SEQUENCE_LENGTH,
        num_calibration_samples=NUM_CALIBRATION_SAMPLES,
    )

    # ======================
    # 6. 简单生成测试
    # ======================
    print("\n\n========== SAMPLE GENERATION ==============")
    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]))
    print("==========================================\n\n")

    # ======================
    # 7. 保存量化后模型
    # ======================
    # 以原模型名 + 后缀的方式命名输出目录
    SAVE_DIR = MODEL_ID.rstrip("/").split("/")[-1] + "-awq-int4-sym"
    print(f"Saving quantized model to {SAVE_DIR} ...")

    model.save_pretrained(SAVE_DIR, save_compressed=True)
    tokenizer.save_pretrained(SAVE_DIR)

    print("Done.")

四、运行脚本

在终端中,确保已经激活 qwen3-awq 环境,然后执行:

bash 复制代码
python awq_int4_qwen3.py

过程大概会经历:

  1. 加载 Qwen3-14B 原始模型(会占较多显存/内存)

  2. 下载并加载 ultrachat_200k 子集(如本地无缓存)

  3. 运行 AWQ INT4 量化

  4. 打印一段示例生成结果

  5. 在当前目录下生成一个新文件夹,如:Qwen3-14B-2-awq-int4-sym,里面包含 config.json, model.safetensors 等压缩权重

相关推荐
用户7624117567051 小时前
第十五章 数据分析
python·数据分析
frankzch1 小时前
Claude 刷新量子电路最优:LLM 与评估器的进化循环怎么搭
人工智能·深度学习·机器学习·语言模型·量子计算
郝学胜_神的一滴1 小时前
游戏设计:原型与开发 05:读懂动态层,理解玩家如何活在游戏世界
人工智能·程序员
用户6698295485291 小时前
同一句话,粤语要贵 24%:我量了 236 对双语文档和 4 种写法
人工智能
阿屿1 小时前
从零手搓 AI 伴侣:Java + 大模型 + 多模态的工程化踩坑实录
人工智能
const_qiu1 小时前
第四章 07:4.7 本章小结
java·运维·服务器·人工智能
cubestudio2 小时前
云原生分布式训练怎么调度才不浪费算力?CubeStudio 分布式训练与加速架构解析(CRD+Operator / gang 调度 / 亲和反亲和 / GPU 利用率 / 共享 GPU)
人工智能·云原生·gpu
老马识码2 小时前
7541 万笔,2424 万美元:x402 真正解决了什么?
人工智能
2601_961963382 小时前
电子合同检索与全文搜索怎么测、怎么选:六个指标 + 五家平台对比 + 八个自测问题
数据库·后端·python·django·智能合约
大明二代2 小时前
从 RAG 到有记忆的 Agent:Mastra Memory 与 PostgreSQL 实战
前端·javascript·人工智能