用 Transformers 原生加载 Qwen3 — Python 开发者的标准做法
Transformers 为什么是必学的
Hugging Face Transformers 是加载和使用开源大模型最标准的方式。Ollama 和 LM Studio 底层也是用它来加载 Hugging Face 格式的模型。学会 Transformers,你可以:
- 直接加载 Hugging Face 上的任何 Qwen3 规格
- 完整控制思考模式(硬开关 + 软开关)
- 接入 LoRA/QLoRA 等微调方案
- 对接 SGLang、vLLM 等推理框架
环境准备
安装依赖
pip install torch transformers accelerate
推荐版本:
- transformers ≥ 4.51.0(早期版本不支持 Qwen3 的思考模式控制)
- torch ≥ 2.3.0
- accelerate:多卡加载时必需
验证版本
import transformers
import torch
print(f"Transformers {transformers.__version__}")
print(f"PyTorch {torch.__version__}")
最简加载 + 对话
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "Qwen/Qwen3-8B"
# 加载 tokenizer 和模型
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype="auto", # 自动选择 FP16/BF16
device_map="auto" # 自动分配到 GPU/CPU
)
# 构造对话
messages = [
{"role": "system", "content": "你是一个有帮助的助手。"},
{"role": "user", "content": "介绍一下你自己。"},
]
# 应用聊天模板(关键:这里控制思考模式)
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
# enable_thinking=True 是默认值
)
# 编码输入
model_inputs = tokenizer(text, return_tensors="pt").to(model.device)
# 生成回复
generated_ids = model.generate(
**model_inputs,
max_new_tokens=512,
temperature=0.7
)
# 解码输出(去掉输入部分)
response = generated_ids[0][model_inputs["input_ids"].shape[1]:]
print(tokenizer.decode(response, skip_special_tokens=True))
控制思考模式
硬开关
在 apply_chat_template 中设置 enable_thinking=False:
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
enable_thinking=False # 强制关闭思考
)
软开关
在消息中加入 /think 或 /no_think:
messages = [
{"role": "system", "content": "你是一个有帮助的助手。"},
{"role": "user", "content": "/no_think 1 + 1 = ?"},
]
多轮对话中的状态
/think 和 /no_think 是有状态的,模型会记住最近的指令:
messages = [
{"role": "user", "content": "/think 证明勾股定理。"},
# 模型思考后回答
{"role": "assistant", "content": "好的,让我来证明..."},
{"role": "user", "content": "/no_think 给我一个反例。"},
# 模型直接回答,不思考
]
流式生成
实时显示模型输出:
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "Qwen/Qwen3-8B"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype="auto",
device_map="auto"
)
messages = [{"role": "user", "content": "介绍一下 Qwen3 的创新点。"}]
text = tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True,
enable_thinking=False # 关闭思考让流式更干净
)
inputs = tokenizer(text, return_tensors="pt").to(model.device)
# streamer 参数实现流式输出
from transformers import TextStreamer
streamer = TextStreamer(tokenizer, skip_prompt=True)
_ = model.generate(
**inputs,
max_new_tokens=1024,
streamer=streamer
)
加载量化模型(省显存)
4bit 量化(QLoRA 兼容)
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
# 4bit 量化配置
quant_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4", # NormalFloat4,推荐
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True # 二次量化,省显存
)
model_name = "Qwen/Qwen3-8B"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config=quant_config,
device_map="auto"
)
# 之后的生成代码不变
8bit 量化类似,把 load_in_4bit 改成 load_in_8bit,其他配置可以简化。
AWQ 量化
pip install autoawq
from transformers import AutoModelForCausalLM, AutoTokenizer
# AWQ 量化模型名称中通常带 -awq
model_name = "Qwen/Qwen3-8B-Instruct-AWQ"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype="auto",
device_map="auto"
)
多 GPU 加载
如果有多个 GPU,可以用 accelerate 自动分配:
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "Qwen/Qwen3-32B" # 大模型需要多卡
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype="auto",
device_map="auto", # 自动在多 GPU + CPU 间分配
trust_remote_code=True
)
用 accelerate launch 启动以获得更好的多卡支持:
accelerate launch --num_processes=2 your_script.py
MoE 模型加载
加载 Qwen3 的 MoE 模型和 Dense 模型完全一样——都是 AutoModelForCausalLM.from_pretrained:
model_name = "Qwen/Qwen3-30B-A3B"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype="auto",
device_map="auto"
)
MoE 模型的激活参数会自动由 Transformers 的 Router 机制处理。你不需要手动指定激活哪个专家——这是模型内部的路由逻辑。
显存估算
以 FP16/BF16 为例:
| 模型 | 原生 FP16 | 4bit 量化 |
|---|---|---|
| Qwen3-0.6B | ~1.2GB | ~0.4GB |
| Qwen3-4B | ~8GB | ~2.5GB |
| Qwen3-8B | ~16GB | ~5GB |
| Qwen3-14B | ~28GB | ~8GB |
| Qwen3-32B | ~64GB | ~16GB |
| Qwen3-30B-A3B | ~60GB | ~15GB |
实际占用还需要加上 KV Cache,建议额外预留 20-30% 显存。
从 ModelScope 加载(国内加速)
国内网络下 Hugging Face 访问慢,可以用 ModelScope:
# 方法一:设置 HF_ENDPOINT 环境变量
import os
os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
# 之后和正常加载一样
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-8B")
或者直接用 ModelScope 的 modelscope 库:
from modelscope import AutoModelForCausalLM, AutoTokenizer
model_name = "qwen/Qwen3-8B" # ModelScope 的命名略有不同
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype="auto", device_map="auto")
与 SGLang / vLLM 集成
如果你需要更高的推理性能,可以把 Transformers 加载的模型传给 SGLang 或 vLLM:
# SGLang
from sglang import Engine
engine = Engine(
model_path="Qwen/Qwen3-8B",
dtype="auto"
)
# vLLM
from vllm import LLM
llm = LLM(
model="Qwen/Qwen3-8B",
dtype="auto"
)
SGLang 和 vLLM 直接从 Hugging Face 下载和加载模型,不需要手动用 Transformers 加载。
常见问题
OOM(Out of Memory)
- 换更小的模型规格
- 用 4bit 或 8bit 量化
- 减少
max_new_tokens - 减少
device_map使用的 GPU 数量
思考模式生成空内容
- 检查
enable_thinking参数是否设置正确 - 确认模型版本支持思考模式(transformers ≥ 4.51.0)
下载慢
- 用 ModelScope 镜像或设置 HF_ENDPOINT 环境变量
- 配置 Hugging Face 代理
相关阅读
- 01-Ollama 一键启动:不想写代码?
- 04-SGLang 推理服务:高性能推理引擎
- 01-思考模式原理:理解思考模式的 token 行为