graph TD
QWEN["Qwen 系列家族 (2024)"]
QWEN --> BASE["Qwen 2.5 Base<br/>(0.5B / 1.5B / 3B / 7B / 14B / 32B / 72B)"]
QWEN --> INSTRUCT["Qwen 2.5 Instruct<br/>(对话模型)"]
QWEN --> CODE["Qwen 2.5-Coder<br/>(7B / 32B)"]
QWEN --> MATH["Qwen 2.5-Math<br/>(数学专用)"]
QWEN --> VL["Qwen 2-VL<br/>(视觉语言 2B / 7B / 72B)"]
QWEN --> AUDIO["Qwen 2-Audio<br/>(语音语言)"]
QWEN --> QWQ["QwQ / Qwen3<br/>(推理增强)"]
QWEN --> MOE["Qwen-MoE<br/>(A14B MoE)"]
第26章 Qwen 系列训推实战
第26章 Qwen 系列训推实战
Qwen 是阿里云开源的大语言模型系列。在中文 NLP 的世界里,Qwen 已经成为事实上的首选开源基座——不是因为它的英文能力有多强,而是因为它在中文理解、多语言支持和代码能力上的综合表现,让它在最需要中文能力的场景中无人能及。
26.1 章节导入
2023 年 8 月,阿里云发布了 Qwen 的第一批模型(1.8B、7B、14B、72B)。与很多”换个数据再训一遍”的开源模型不同,Qwen 从第一天就在架构层面做了针对中文的深度优化——最显著的标志是一个包含 151,851 个 token 的超大词表。
到 2024 年,Qwen 已经发展为一个庞大的模型家族:
本章将深入 Qwen 的架构设计、QwQ 推理模型、Qwen-VL 多模态架构,以及”训推一体”的工程实践。
26.2 架构设计
26.2.1 大词表设计
Qwen 最鲜明的架构特征是它的大词表——151,851 个 token,远超 LLaMA 2(32K)和 LLaMA 3(128K)。
为什么要这么大的词表?因为中文编码效率。
句子: "人工智能是计算机科学的一个分支"
LLaMA 2 tokenizer (32K vocab):
→ 人工(3) 智能(3) 是(1) 计算机(4) 科学(3) 的(1) 一个(2) 分支(3)
→ 总计 ~20 tokens
LLaMA 3 tokenizer (128K vocab):
→ 人工(1) 智能(1) 是(1) 计算机(1) 科学(1) 的(1) 一个(1) 分支(1)
→ 总计 ~10 tokens
Qwen tokenizer (151K vocab):
→ 人工智能(1) 是(1) 计算机(1) 科学(1) 的(1) 一个(1) 分支(1)
→ 总计 ~8 tokens("人工智能"是一个 token!)
更少的 token 数意味着: 1. 推理更快:序列更短,Attention 计算量更小 2. 上下文更长:同样的 token 限制下能放更多内容 3. API 更便宜:按 token 计费时成本更低 4. 编码效率更高:特别是中文密集场景
但大词表也有代价——Embedding 层和 Output Head 的参数量很大:
# Qwen 7B 的 Embedding 参数计算
vocab_size = 151851
hidden_dim = 4096
embedding_params = vocab_size * hidden_dim # = 622,616,576 ≈ 623M
# 占 7B 总参数的 ~9%
# 对比 LLaMA 2 7B
llama_vocab = 32000
llama_embedding = llama_vocab * 4096 # = 131M (仅 1.9%)26.2.2 整体架构
Qwen 2.5 的架构与 LLaMA 非常相似,但有几个关键差异:
graph TD
A["Input Tokens"] --> B["Token Embedding<br/>(151K vocab)"]
B --> C["RoPE (无绝对位置编码)"]
C --> D["Transformer Blocks × N"]
D --> E["RMSNorm"]
E --> F["LM Head (tied weights)"]
subgraph "Qwen Transformer Block"
G["RMSNorm"] --> H["Grouped Query Attention<br/>+ RoPE + QKV Bias"]
H --> I["Residual + Dropout"]
I --> J["RMSNorm"]
J --> K["SwiGLU FFN"]
K --> L["Residual + Dropout"]
end
D --> G
Qwen 的几个独有设计:
- QKV Bias:在 Attention 的 QKV 投影中加了 bias 项——LLaMA 没有。这对某些需要位置敏感的任务有帮助。
- Tied Embeddings(小模型):Qwen 0.5B/1.5B 将 Input Embedding 和 Output Head 共享权重以节省参数。大模型(7B+)则不共享。
- Tokenizer 设计:基于 BBPE(Byte-level BPE),对中文、日文、韩文做了专门的词表优化。
26.2.3 主要模型规格
| 配置 | Qwen 2.5 0.5B | Qwen 2.5 7B | Qwen 2.5 14B | Qwen 2.5 72B |
|---|---|---|---|---|
| Layers | 24 | 28 | 48 | 80 |
| Dim | 896 | 3584 | 5120 | 8192 |
| Heads | 14 | 28 | 40 | 64 |
| KV Heads | 2 | 4 | 8 | 8 |
| FFN Dim | 4864 | 18944 | 13824 | 29568 |
| Vocab | 151,936 | 151,936 | 151,936 | 151,936 |
| Context | 32K | 128K | 128K | 128K |
| Params | 0.49B | 7.62B | 14.7B | 72.7B |
注意 KV Heads 的激进压缩:Qwen 2.5 7B 只有 4 个 KV Heads(Query 有 28 个),GQA ratio 是 7:1。这比 LLaMA 3 8B 的 4 个 KV Heads(32 个 Query,8:1)更加激进。这是为什么 Qwen 在长上下文推理时显存效率特别好。
26.3 QwQ 推理增强模型
26.3.1 什么是 QwQ
QwQ(Qwen with Questions)是阿里在 2024 年底发布的推理增强模型,对标 OpenAI 的 o1。与标准 Instruct 模型不同,QwQ 会先进行长链式思维(Chain-of-Thought)再给出答案。
用户问题: "一个水池有两个进水管,A管单独注满需要6小时,B管需要8小时,
一个出水管C单独排完需要12小时。三管同时开,几小时注满?"
标准模型直接给答案: 4.8小时(可能没有过程)
QwQ 的推理过程:
[Thinking] 让我一步步分析...
首先,计算每个管道的流量(以水池容量为单位):
- A管进水速度:1/6 池/小时
- B管进水速度:1/8 池/小时
- C管排水速度:1/12 池/小时
三管同时开启时的净流量:
1/6 + 1/8 - 1/12 = 4/24 + 3/24 - 2/24 = 5/24 池/小时
注满时间 = 1 / (5/24) = 24/5 = 4.8 小时
[Answer] 三管同时开启,需要 4.8 小时注满水池。
26.3.2 推理增强模型的训练
QwQ 的训练方法(基于社区的逆向推测)大概率遵循以下范式:
graph TD
A["Qwen Base Model"] --> B["SFT<br/>(大量 CoT 数据)"]
B --> C["RL on Math/Code<br/>(有明确答案的验证)"]
C --> D["RL on General<br/>(开放问题)"]
D --> E["QwQ"]
F["数学题 + 解答"] --> B
G["代码题 + 推理过程"] --> B
H["验证器 / 执行器"] --> C
关键创新在于强化学习阶段——不像 RLHF 那样依赖人类标注偏好,而是使用可验证的奖励(数学题有标准答案,代码可以执行测试)。
# 推理增强模型的奖励函数示例
def math_reward(response, ground_truth):
"""从模型回复中提取答案,与标准答案比较"""
answer = extract_final_answer(response) # 提取 \\boxed{} 中的内容
try:
if float(answer) == float(ground_truth):
return 1.0
elif abs(float(answer) - float(ground_truth)) < 1e-6:
return 0.8 # 数值近似
else:
return 0.0
except:
return 0.0
def code_reward(response, test_cases):
"""执行模型生成的代码,跑测试用例"""
code = extract_code(response)
passed = 0
total = len(test_cases)
for test in test_cases:
try:
result = execute(code, test["input"])
if result == test["expected"]:
passed += 1
except:
pass
return passed / total26.3.3 QwQ 的推理服务挑战
推理增强模型在服务部署上有一个新的挑战:推理过程很长。一个数学题可能需要 1000-10000 token 的思维链,但用户只想看最终答案。
# QwQ 部署需要特别配置
vllm serve Qwen/QwQ-32B-Preview \
--tensor-parallel-size 2 \
--max-model-len 32768 \ # 需要支持长思维链
--max-num-seqs 32 \ # 但单请求 token 很多,batch 不能太大
--enable-prefix-caching \ # 推理过程可缓存
--gpu-memory-utilization 0.92推理模型的成本问题:QwQ-32B 处理一个复杂数学题可能需要 5000+ token 的思维链。如果按 token 计费,用户需要为”思考过程”付费——但这个过程对用户不一定有直接价值。OpenAI 的 o1 系列也面临同样的问题。在生产环境中,需要让用户明确知道推理成本,或提供”快速模式”(跳过思维链)选项。
26.4 Qwen-VL 多模态架构
26.4.1 架构概览
Qwen-VL(Vision-Language)是 Qwen 的多模态扩展。它不是一个从头训练的多模态模型,而是使用模块化拼接的方式——预训练的 Vision Encoder + LLM,通过 Adapter 连接。
graph TD
A["图像输入"] --> B["ViT Vision Encoder<br/>(OpenCLIP ViT-bigG)"]
B --> C["图像 Patches<br/>(256x256 → patch embeddings)"]
C --> D["Vision-Language Adapter<br/>(MLP + Cross Attention)"]
D --> E["视觉 Token 序列"]
F["文本输入"] --> G["Text Tokenizer<br/>(Qwen BBPE)"]
G --> H["文本 Token 序列"]
E --> I["拼接: [视觉 tokens] + [文本 tokens]"]
H --> I
I --> J["Qwen LLM<br/>(标准 Transformer)"]
J --> K["输出"]
26.4.2 Vision-Language Adapter
Qwen-VL 的关键组件是 VL Adapter,它负责将视觉特征对齐到语言空间:
# Qwen-VL Adapter 的简化架构
class VLAdapter(nn.Module):
def __init__(self, vision_dim=1664, llm_dim=4096, num_query=256):
super().__init__()
# 方式1:Cross Attention(Qwen-VL v1)
self.cross_attn = nn.MultiheadAttention(
embed_dim=llm_dim,
num_heads=16,
kdim=vision_dim,
vdim=vision_dim
)
# 可学习的 Query tokens
self.query_embed = nn.Parameter(torch.randn(num_query, llm_dim))
# 方式2:简单 MLP(Qwen-VL v2)
self.mlp = nn.Sequential(
nn.Linear(vision_dim, llm_dim * 2),
nn.GELU(),
nn.Linear(llm_dim * 2, llm_dim)
)
def forward(self, vision_features):
# vision_features: [num_patches, vision_dim]
# Cross Attention 路径
query = self.query_embed.unsqueeze(1) # [num_query, 1, llm_dim]
# 固定数量的 query tokens 从视觉特征中提取信息
visual_tokens, _ = self.cross_attn(
query, vision_features, vision_features
) # [num_query, 1, llm_dim]
return visual_tokens.squeeze(1) # [num_query, llm_dim]Qwen 2-VL 引入了 Naive Dynamic Resolution——根据图像的实际大小动态调整 patch 数量,而不是将所有图像 resize 到固定大小。这对文档理解、长截图等场景非常重要。
26.4.3 Qwen-VL 的训练
# Qwen-VL 训练阶段(简化)
stages:
- name: "Stage 1: Vision Encoder 预训练"
description: "在大量图像-文本对上训练 ViT"
data: "LAION-400M / COYO-700M"
- name: "Stage 2: VL Adapter 训练"
description: "冻结 ViT 和 LLM,只训练 Adapter"
data: "图像-文本对(详细描述、QA)"
frozen: ["ViT", "LLM"]
trainable: ["VL Adapter"]
- name: "Stage 3: 端到端微调"
description: "解冻 LLM,整体微调"
data: "多模态指令数据"
frozen: ["ViT"]
trainable: ["VL Adapter", "LLM"]26.5 训推一体的工程实践
26.5.1 Qwen 的全栈工具链
Qwen 与其他开源模型最大的差异化不在于模型质量,而在于全栈工具链的完整性。阿里为 Qwen 提供了从训练到部署的完整支持:
graph LR
subgraph "训练工具"
A["Qwen-Agent<br/>(框架)"]
B["EasyNLP<br/>(训练框架)"]
C["ModelScope<br/>(模型中心)"]
end
subgraph "部署工具"
D["DashScope API<br/>(云服务)"]
E["vLLM 支持<br/>(开源部署)"]
F["Ollama 支持<br/>(本地部署)"]
end
subgraph "应用工具"
G["Qwen-Agent<br/>(Agent 应用)"]
H["通义千问 App<br/>(消费端)"]
I["阿里云百炼<br/>(企业平台)"]
end
A --> G
B --> E
C --> F
26.5.2 使用 vLLM 部署 Qwen
# Qwen 2.5 7B 部署(单卡)
vllm serve Qwen/Qwen2.5-7B-Instruct \
--port 8000 \
--max-model-len 32768 \
--enable-prefix-caching \
--gpu-memory-utilization 0.9
# Qwen 2.5 72B 部署(4卡)
vllm serve Qwen/Qwen2.5-72B-Instruct \
--tensor-parallel-size 4 \
--max-model-len 65536 \
--enable-prefix-caching \
--quantization fp8
# Qwen 2-VL 部署(视觉语言模型)
vllm serve Qwen/Qwen2-VL-7B-Instruct \
--port 8000 \
--max-model-len 32768 \
--trust-remote-code26.5.3 LoRA 微调 Qwen
# 使用 LLaMA-Factory 微调 Qwen(社区最流行方案)
from llama_factory import create_args, run_sft
args = create_args(
model_name_or_path="Qwen/Qwen2.5-7B",
dataset="your_dataset", # 在 data/dataset_info.json 中注册
finetuning_type="lora",
lora_target=["q_proj", "k_proj", "v_proj", "o_proj"],
lora_rank=32,
lora_alpha=64,
learning_rate=5e-5,
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
cutoff_len=4096,
output_dir="./qwen-lora-output",
fp16=False,
bf16=True,
)
run_sft(args)# 或使用 YAML 配置文件
# qwen_finetune.yaml
### model
model_name_or_path: Qwen/Qwen2.5-7B
trust_remote_code: true
### method
stage: sft
do_train: true
finetuning_type: lora
lora_target: q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj
lora_rank: 32
lora_alpha: 64
### dataset
dataset: my_data
template: qwen
cutoff_len: 4096
overwrite_cache: true
### output
output_dir: ./output/qwen-7b-lora
logging_steps: 10
save_steps: 500
### train
per_device_train_batch_size: 4
gradient_accumulation_steps: 4
learning_rate: 5e-5
num_train_epochs: 3
warmup_ratio: 0.03
lr_scheduler_type: cosine
bf16: true
flash_attn: fa2 # 使用 FlashAttention 2# 启动微调
llamafactory-cli train qwen_finetune.yaml
# 合并 LoRA 权重
llamafactory-cli export \
--model_name_or_path Qwen/Qwen2.5-7B \
--adapter_name_or_path ./output/qwen-7b-lora \
--export_dir ./output/qwen-7b-merged26.5.4 Qwen-Agent:内置 Agent 框架
# Qwen-Agent 示例
from qwen_agent.agents import Assistant
from qwen_agent.tools import code_interpreter
# 定义工具
tools = [
{"type": "code_interpreter"}, # 代码执行
# 可以添加自定义工具
]
# 创建 Agent
agent = Assistant(
llm={"model": "Qwen/Qwen2.5-7B-Instruct"},
function_list=tools,
system_message="你是一个数据分析助手,擅长用 Python 解决数据分析问题。"
)
# 运行
messages = [{"role": "user", "content": "帮我分析一下这个 CSV 文件的统计数据"}]
for response in agent.run(messages):
print(response)26.6 Qwen vs LLaMA 全面对比
| 维度 | Qwen 2.5 72B | LLaMA 3.1 70B |
|---|---|---|
| 英文能力 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 中文能力 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 代码能力 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 数学能力 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| Vocab 大小 | 151,936 | 128,256 |
| KV Heads | 8 | 8 |
| 上下文 | 128K | 128K |
| 推理速度(中文) | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 推理速度(英文) | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 微调生态 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 部署便捷度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
Qwen 的中文优势在哪些场景最明显? 1. 法律/合同文本:中文专业术语的编码效率和准确性 2. 古文/文学:Qwen 对文言文的理解远超 LLaMA 3. 客服/对话:更自然的中文表达,不像翻译腔 4. 代码注释/文档生成:中文注释的质量 5. 表格/结构化数据:中文表头和内容的理解
26.7 实践建议
选型建议: 1. 面向中文用户 → Qwen:毫无疑问,中文场景 Qwen 全面领先 2. 多语言服务 → Qwen:Qwen 的词表覆盖 29+ 种语言 3. 英文为主 → LLaMA 3:英文质量略优,生态更成熟 4. 需要推理能力 → QwQ:开源推理模型中最强的选择之一 5. 需要多模态 → Qwen-VL:模块化设计,部署灵活 6. 资源受限 → Qwen 2.5 3B:3B 参数量但能力出色
Qwen 部署的注意事项: 1. FlashAttention 版本:Qwen 需要 FlashAttention 2 或以上,旧版本可能有兼容性问题 2. Tokenizer 版本:Qwen 2.5 的 tokenizer 与 Qwen 1 不兼容,升级时必须同时更新数据处理管线 3. Chat Template:Qwen 使用 <|im_start|> 和 <|im_end|> 作为对话标记,与 LLaMA 的格式不同 4. 大词表的显存开销:151K vocab 的 Embedding 层在 FP16 下占 ~1.2GB(72B 模型),推理时需要确保有足够余量
26.8 小结
Qwen 系列代表了中国 AI 团队在大模型领域的工程实力。它没有革命性的架构创新——大部分技术与 LLaMA 一脉相承——但它的价值在于针对中文场景的系统化优化:
- 大词表解决了中文编码效率问题
- QwQ 用可验证奖励的 RL 方法实现了推理增强
- Qwen-VL 用模块化方式实现了多模态
- 完整的工具链让从训练到部署的每个环节都有官方支持
在中文 NLP 场景,Qwen 已经是开源模型的首选。
26.9 延伸阅读
- Qwen Team (2024). Qwen2.5 Technical Report. arXiv:2412.15115
- Bai et al. (2023). Qwen Technical Report. arXiv:2309.16609
- Wang et al. (2024). Qwen2-VL: Enhancing Vision-Language Model’s Perception of the World at Any Resolution. arXiv:2409.12191
- Qwen-Agent 项目:https://github.com/QwenLM/Qwen-Agent
- LLaMA-Factory(微调工具):https://github.com/hiyouga/LLaMA-Factory
- ModelScope(模型中心):https://modelscope.cn