Qwen 系列模型深度学习笔记
覆盖范围:Qwen1 → Qwen1.5 → Qwen2 → Qwen2.5 → Qwen3 → Qwen3.5 学习方式:螺旋上升式深度解析,从基石到前沿
目录
- Qwen 系列演进总览
- Qwen1:基石奠定
- Qwen1.5:稳步迭代
- Qwen2:全面升级
- Qwen2.5:数据与后训练的突破
- Qwen3:推理与效率的融合
- Qwen3.5:迈向原生多模态智能体
- 横向对比与关键演进主线
1. Qwen 系列演进总览
Qwen1.0 & 1.5 → 高质量数据清洗 + 基础 Transformer 架构
Qwen2 & 2.5 → 全注意力架构推向 72B,代码和数学能力突破
Qwen3 → 长上下文 + 推理能力(Thinking Mode)结合,引入 MoE
Qwen3VL → 加入视觉编码器和 MRoPE,引入 DeepStack 多层级视觉特征注入
Qwen3Next → 引入 GatedDeltaNet + Gated Attention 混合注意力 + 共享专家
Qwen3.5 → 在 Qwen3Next 基础上加入 MRoPE + Vision,拆分投影层,去掉 DeepStack核心演进主线:
| 维度 | 演进轨迹 |
|---|---|
| 注意力机制 | MHA → GQA → Q/K Norm → Gated Attention → GatedDeltaNet 混合 |
| 长度外推 | 动态NTK → YaRN+DCA → ABF → MRoPE + Partial RoPE |
| 训练效率 | BF16 → FP8 流水线 |
| 对齐训练 | RLHF → Constitutional AI → Online Merging → 四阶段后训练 → 异步RL |
| 多模态 | 无 → 后融合(Qwen3VL) → Early Fusion(Qwen3.5) |
| MoE规模 | 60专家 → 256专家 → 512专家 |
2. Qwen1:基石奠定
论文:QWEN TECHNICAL REPORT
2.1 模型结构
词表设计(152K)
- 基础:tiktoken BPE,选择
cl100k_base作为起点 - 扩充中文词汇:让中文不再被拆得七零八落
- 数字单独拆分:
2048→2,0,4,8
数字拆分的权衡:
优点:
→ 模型能感知数字结构(1024 和 2048 都以 0,4,8 结尾)
→ 数学推理能力显著提升
代价:
→ 1000000000 → 10个token(原来1个)
→ 金融、科学类文本序列长度急剧膨胀
→ 消耗宝贵的上下文窗口Untied Embedding(解耦嵌入)
标准 LLM 的输入嵌入矩阵 = 输出嵌入矩阵(权重共享),而 Qwen1 将两者拆分:
| 输入侧(理解词) | 输出侧(生成词) | |
|---|---|---|
| 目标 | 把 token 映射成语义向量 | 把向量还原成最可能的下一个 token |
| 关心的 | 与上下文的相似关系 | 词表中的概率分布 |
| 本质 | 做检索(我是谁?) | 做排名(谁最可能出现?) |
结论:理解是"聚合语义",生成是"竞争排名",强迫共用同一套参数是在让一个人同时用同一只手写字和打架——能做,但都做不到最好。代价是增加内存消耗,但可以显著提升模型性能。
Pre-RMSNorm
Pre-Norm vs Post-Norm:
Post-Norm(旧方式):每层操作完再归一化
→ 理论上限更高,但深层网络梯度不稳定
→ 需要精细的学习率调参
Pre-Norm(Qwen选择):每层操作前先归一化
→ 梯度回传时每层输入幅度可控
→ 训练稳定,可用更大学习率
→ 更容易 Scale 到大模型RMSNorm vs LayerNorm:
# LayerNorm(完整版)
mean = x.mean()
var = x.var()
x_norm = (x - mean) / sqrt(var + ε)
# RMSNorm(砍掉均值计算)
rms = sqrt(mean(x²) + ε)
x_norm = x / rms均值计算对模型效果贡献极小,砍掉后计算更快,效果几乎不变。
ε 的作用:防止分母为零或极小时的数值不稳定(数值爆炸)。
SwiGLU 激活函数
ReLU 的问题:负数区域梯度为0,神经元可能永久失活。
SwiGLU 的门控机制:
gate = Linear1(x) # 门控分支
signal = Linear2(x) # 信号分支
output = signal * Swish(gate)
# Swish(x) = x * sigmoid(x),平滑版ReLUFFN 维度调整:SwiGLU 有3个矩阵,标准FFN有2个。为保持参数量不变:
2 × d_model × d_ff = 3 × d_model × d_ff_new
→ d_ff_new = (2/3) × d_ff所以使用 SwiGLU 的模型 FFN 隐藏维度是原始的 2/3。
RoPE 位置编码
传统正弦编码的问题:编码的是绝对位置,超出训练长度的位置从未见过,模型完全懵掉。
RoPE 的核心洞察:Attention 机制真正需要的不是"我在第几位",而是"我和你之间差了几位"。
数学推导:
位置 m 的向量旋转角度 mθ
位置 n 的向量旋转角度 nθ
点积结果:
cos(mθ) × cos(nθ) + sin(mθ) × sin(nθ) = cos((m-n)θ)
→ 相对位置 (m-n) 自动从点积里冒出来!
→ 天然支持长度外推实现方式:每两个维度一组进行旋转,不同维度用不同的 θ:
θ_i = 10000^(-2i/d)
# 低维度:θ大 → 旋转快 → 捕捉短距离关系(类比秒针)
# 高维度:θ小 → 旋转慢 → 捕捉长距离关系(类比时针)QKV 层保留 Bias
大多数层移除 bias(被 RMSNorm 抵消,浪费参数),但 QKV 层保留 bias:
Q = x @ Wq + bq
K = x @ Wk + bk
bias 提供固定的"基准值"(锚点)
→ 遇到训练时没见过的位置
→ bias 提供稳定的参考
→ 外推时更稳定
类比:口袋里的纸质地图 vs 纯依赖GPS2.2 长度外推技术(2048 → 8192)
三种技术组合,各司其职:
动态 NTK 插值
NTK 的本质:修改 RoPE 底数,让所有维度"转慢一点",防止高频混叠。
# 原始 RoPE
θ_i = 10000 ^ (-2i/d)
# 静态 NTK(固定底数)
k = 目标长度 / 训练长度 # 如 8192/2048 = 4
new_base = 10000 * (k ^ (d/(d-2)))
# 动态 NTK(按需放大)
def get_base(current_len, train_len=2048):
if current_len <= train_len:
return 10000 # 短序列:原汁原味
k = current_len / train_len
return 10000 * (k ^ (d/(d-2))) # 长序列:按需扩展底数变大 → θ_i 变小 → 旋转变慢 → 不越界
三种外推方法对比:
| 方法 | 核心思路 | 解决了什么 | 引入了什么问题 |
|---|---|---|---|
| 线性插值 | 位置等比例压缩 | 越界问题 | 短距离感知模糊 |
| 静态 NTK | 固定放大底数 | 越界+精度 | 短序列精度白白损失 |
| 动态 NTK | 按需放大底数 | 两者兼顾 | 无明显缺陷 |
| YaRN | 低频插值+高频不动 | 更精细处理 | 实现更复杂 |
LogN-Scaling
问题:序列变长时,softmax 在更多值中分配注意力权重,导致注意力分布极度分散(聚光灯变泛光灯)。
解法:
普通 Attention:scale = 1/√d(固定)
LogN-Scaling: scale = κ·log(n)/d(随序列长度增大)
n 变长 → log(n) 变大 → scale 变大
→ logits 整体放大
→ softmax 输出更集中
→ 注意力熵保持稳定(熵不变性)分层窗口 Self-Attention
低层(捕捉局部语法):短窗口
→ 主谓宾关系只需要4-8个词的窗口
高层(捕捉全局语义):长窗口
→ 文章主题需要看全文
效果:按需分配算力
底层:短窗口×多层 → 省算力,够用
顶层:长窗口×少层 → 花算力,值得2.3 模型训练
| 配置项 | 值 | 说明 |
|---|---|---|
| 训练目标 | 标准自回归语言模型 | 预测下一个 token |
| 上下文长度 | 2048 | 训练时固定 |
| 注意力 | Flash Attention | 提高计算效率 |
| 精度 | BF16 混合精度 | 速度+稳定性 |
| 优化器 | AdamW | β1=0.9, β2=0.95, ε=1e-8 |
| 学习率 | 余弦衰减到峰值的10% | 保留微调空间 |
β2=0.95 的原因:
有效记忆窗口 = 1/(1-β2)
β2=0.999 → 记忆1000步(小模型,梯度噪声大)
β2=0.95 → 记忆20步(大模型,batch极大,梯度已准确)
大模型训练 batch size 极大 → 每步梯度噪声小
→ 不需要平均那么长的历史
→ 更快响应当前梯度方向余弦衰减到10%而非0%:
降到0%:参数完全停止更新,无法微调落点
保留10%:
→ 继续以极小步长游走
→ 跳出训练末期的微小局部极小值
→ 在损失曲面的"平坦区域"(Flat Minima)落脚
→ 测试集偏移时损失变化平缓,泛化更好Document Packing(文档打包):
问题:文档长度分布极不均匀
→ 短文档(20-100 tokens) padding 到 2048
→ 97%的计算浪费在 PAD token 上
解法:随机打乱多篇文档并拼接至 2048
→ 消灭 PAD,算力不浪费
副作用:跨文档注意力污染
解法:块对角因果 Mask块对角因果 Mask 示意:
A1 A2 A3 B1 B2 B3
A1 [ 1 0 0 0 0 0 ]
A2 [ 1 1 0 0 0 0 ]
A3 [ 1 1 1 0 0 0 ]
B1 [ 0 0 0 1 0 0 ] ← B1只看自己文档
B2 [ 0 0 0 1 1 0 ]
B3 [ 0 0 0 1 1 1 ]工程实现使用 FlashAttention 的变长版本(varlen):
from flash_attn import flash_attn_varlen_func
output = flash_attn_varlen_func(
q, k, v,
cu_seqlens_q, # 每个文档的累积长度 [0, 3, 6]
cu_seqlens_k,
max_seqlen_q,
max_seqlen_k,
causal=True
)为什么要随机打乱:防止灾难性遗忘(Catastrophic Forgetting)。相同领域文档集中训练会导致梯度长期偏向同一方向,其他领域能力退化。随机打乱保证每个 batch 都是整体数据分布的无偏估计(i.i.d 采样)。
2.4 Reward Model 训练体系
奖励模型结构:
class QwenRewardModel(nn.Module):
def __init__(self):
self.qwen = QwenModel() # 同等大小的 Qwen 模型
self.pooling = nn.Linear(hidden_size, 1) # 池化层输出标量奖励
def forward(self, input_ids):
hidden_states = self.qwen(input_ids)
eos_hidden = hidden_states[:, -1, :] # EOS token 位置
reward = self.pooling(eos_hidden)
return reward为什么用 EOS token:EOS 经过所有层的注意力计算,其隐藏状态已经"看过并总结了"整个序列的信息,是回答质量的天然压缩表示。
三重保障机制:
- 6600标签分类系统:预先设计覆盖所有领域的"地图",确保偏好数据覆盖广度
- 平衡采样算法:每个标签桶贡献相同数量的样本,防止高频领域主导训练
- 多样性回答生成:用不同规模+不同采样策略的 Qwen 模型生成回答,提高标注质量
为什么需要多样性:若 RM 只见过数学题的偏好对,它对写诗、编程等领域的判断力将完全失效(Out-of-Distribution Generalization Failure)。
3. Qwen1.5:稳步迭代
注:无正式技术报告,有两篇官方介绍博客。
3.1 模型结构
- 黄金四件套:Tokenizer BPE + PreRMSNorm + SwiGLU + RoPE
- Flash Attention:使用
torch.nn.functional.scaled_dot_product_attention(SDPA)实现 - GQA:仅 Qwen1.5-32B 使用 Grouped Query Attention
- Untied Embedding:延续 Qwen1,
tie_word_embedding=False - QKV bias:延续 Qwen1,只在 QKV 参数里加 bias
3.2 Qwen1.5-MoE-A2.7B
MoE 基本原理:
Dense 模型:每个 token 激活所有 FFN 参数(14B模型推理用全部14B参数)
MoE 模型:每个 token 只激活部分"专家"(总参数14B,每次只用2-3B)Qwen1.5 MoE 架构细节:
- 细粒度专家:将 FFN 切分为多个小块,每小块是独立专家
- 路由机制:4个共享专家 + 60个路由专家(每次激活4个)
粗粒度8专家选2:C(8,2)=28种组合
细粒度60专家选4:C(60,4)=487635种组合
→ 细粒度表达能力指数级增大初始化策略:
从 Qwen-1.8B 继承初始化:
→ 把1.8B的FFN权重复制并切分到各专家
→ 每个专家起点已有基础能力
→ 收敛速度大幅提升
引入随机扰动:
→ 打破所有专家完全相同的对称性
→ 专家开始分化,各司其职专家坍缩问题与负载均衡损失:
问题:路由器发现专家A最好 → 全部token路由给A → A更强 → 恶性循环
→ 最终只有1个专家在工作,MoE退化为Dense模型
解法:负载均衡损失
loss = cross_entropy_loss + α * load_balance_loss
load_balance_loss = Σ(usage_i - 1/n_experts)²
→ 越均匀损失越小
→ 梯度惩罚路由器,迫使分散分配
α = 0.01 ~ 0.1(轻微惩罚,非强制均分)3.3 模型训练
- 数据量未公布
- 偏好对齐:PPO 和 DPO 都用到了
- 全系列支持 32K 上下文
- 提供 AWQ 和 GPTQ 量化模型(int4/int8)
3.4 模型量化:AWQ vs GPTQ
朴素 INT4 量化的问题:
所有权重一视同仁四舍五入
→ 重要权重被破坏(激活值大的权重,四舍五入一点点就导致输出剧变)
→ 模型质量严重下降AWQ(Activation-Weighted Quantization):
# 核心思路:不是跳过重要权重,而是先放大再量化
# 计算重要性
importance = activation.abs().mean() # 激活值越大,权重越重要
# 重要权重的处理
scale = activation ** 0.5 # 根据激活值计算缩放因子
w_scaled = w * scale # 放大重要权重
w_int4 = round(w_scaled / quant_scale) # 量化(相对误差更小)
# 推理时除回去,误差已被压缩放大效果类比:
直接量化:精密零件1.2345米 → 四舍五入 → 1米(误差0.2345米)
AWQ:先×100=123.45厘米 → 四舍五入 → 123厘米 → ÷100 → 1.23米(误差0.0045米)AWQ vs GPTQ 对比:
| AWQ | GPTQ | |
|---|---|---|
| 核心原理 | 激活值缩放 | 逐层误差补偿 |
| 运行环境 | CPU也能跑 | 需要GPU |
| 速度 | 快 | 慢 |
| 精度 | 接近GPTQ | 略高 |
| 工业选择 | 部署速度优先 | 精度优先 |
4. Qwen2:全面升级
论文:QWEN2 TECHNICAL REPORT
4.1 模型结构
与 Qwen1 的主要区别:
- GQA(Grouped Query Attention):全系列标配
- YaRN + DCA:替代动态 NTK,更精细的长度外推
- Tokenizer:升级为 BBPE,词表 151643
GQA(分组查询注意力)
MHA(标准):Q头数=K头数=V头数(如32:32:32)
GQA: Q头数 > K头数=V头数(如32:4:4)
→ K和V参数大幅缩减
→ KV Cache 显存大幅降低
→ 推理速度提升YaRN(进阶长度外推)
YaRN 在 NTK 基础上做了分频段处理:
低频维度(旋转慢的维度):做插值压缩
高频维度(旋转快的维度):保持不动
对比:
NTK:整体缩放,高频维度也被压缩
YaRN:分别处理,高频维度精度不损失
优势:
→ 保住了短距离精度(高频不动)
→ 扩展了长距离范围(低频插值)
→ 两全其美DCA(Dual Chunk Attention,双块注意力)
解决超长序列下全注意力的计算效率问题:将序列分成若干块,块内做完整注意力,块间通过特殊机制交互,在保持精度的同时降低计算复杂度。
BBPE(Byte-level BPE)
BPE 的问题:
遇到生僻字或新语言:
泰语:ไม่มีวันสิ้นสุด → BPE词表里没有 → [UNK]
→ 模型完全看不懂BBPE 的解法:
从字节(Byte)出发,而非字符:
'A' → 0x41(1字节)
'中' → 0xE4 B8 AD(3字节)
'ไ' → 0xE0 B9 84(3字节)
→ 任何语言都能用256个基础字节表示
→ 永远不会出现 UNK
→ 新语言零成本支持4.2 预训练
三大改进:
- 质量提升:额外的启发式方法 + 基于模型的过滤(用 Qwen 模型过滤低质量数据),合成高质量预训练数据
- 数据扩展:更大规模的高质量代码、数学和多语言数据,支持约30种语言
- 分布改进:在小规模模型上实验,优化不同来源和领域的数据混合
4.3 后训练数据合成
拒绝采样(Rejection Sampling):
针对数学等有明确答案的任务:
→ 生成100条推理链
→ 只保留答案正确的
→ 错误推理全部丢弃
→ 保证数据质量执行反馈(Execution Feedback):
针对 coding 任务:
→ LLM 生成代码 + 相关测试用例
→ 实际编译执行评估有效性
→ 创建演示和偏好数据
对于指令跟随:
→ 对每个有约束的指令,LLM 生成 Python 验证函数
→ 确保响应符合指令要求(如长度限制)数据再利用:
文学写作任务中,注释者难以创作高质量响应
→ 收集高质量公共领域文学作品
→ 用 LLM 开发不同细节级别的指令
→ 指令与原始作品配对作为 demo 数据4.4 RLHF 两阶段训练
离线训练阶段:使用预先收集的偏好数据集进行 DPO 训练
在线训练阶段:
从当前策略模型中采样多个 response
→ 奖励模型选择最受欢迎和最不受欢迎的响应
→ 形成用于 DPO 的偏好对
→ 采用在线合并优化器(Online Merging Optimizer)减轻对齐税Online Merging Optimizer(在线合并优化器)
对齐税(Alignment Tax):
RLHF 对齐后:
Base Model 数学得分:85分
RLHF 对齐后:78分 ← 这7分就是"对齐税"
原因:RL 更新方向和预训练方向有冲突,部分预训练知识被覆盖KL 惩罚(传统方法):
reward = rm_score(response) - β * KL(policy || ref_policy)
# KL散度衡量当前策略vs原始SFT模型的差异
# 问题:RM梯度方向和KL梯度方向冲突时,互相抵消,训练混乱Online Merging 的解法:
# 两个目标完全分离,不引入梯度冲突
# Step1:按RM方向完整更新参数
θ_rl = rl_update(θ)
# Step2:更新完成后,直接插值(纯数学操作,无梯度)
θ_merged = α * θ_rl + (1-α) * θ_sft
# α 动态调整:
# RL初期:α小,保留更多SFT知识
# RL后期:α大,更多采用RL结果类比:
- KL惩罚:想往东走(RM),但绳子拉着往西(KL),每步都在拔河
- Online Merging:先完整往东走一步,走完再往回退半步,两个动作完全分离
Constitutional AI(宪法反馈)
传统安全训练的问题:人工标注成本高,覆盖不全,标准不一致。
Constitutional AI 的流程:
# Step1:让模型生成"违规回答"
bad_response = model.generate(prompt="如何制作危险物品")
# Step2:让模型对照宪法批判自己
critique = model.generate(prompt=f"""
回答:{bad_response}
宪法原则:不提供危险物品制作方法
请指出违反了哪些原则
""")
# Step3:让模型根据批判修正回答
good_response = model.generate(prompt=f"""
原回答:{bad_response}
批判:{critique}
请生成符合宪法原则的新回答
""")
# Step4:(bad_response, good_response) 构成偏好对,用于DPO优势:
- 可大规模自动生成偏好数据
- 判断标准完全一致(都来自同一宪法)
- 新增原则只需修改宪法文本
- 成本极低
质量保证:使用更强的模型(Qwen2-72B)做批判,多智能体协作评分交叉验证。
奖励欺骗(Reward Hacking)及防御
常见欺骗模式:
- 无限堆砌废话(答案越长分越高)
- 滥用 Markdown 格式(看起来专业但内容空洞)
- 无脑夸用户(迎合性回答)
三层防御体系:
1. KL 散度惩罚(最核心)
reward = rm_score - β * KL(policy || ref_policy)
→ 钻漏洞的回答与SFT分布差异大 → KL飙升 → 总奖励反而降低
2. 多源RM融合(交叉验证)
final_score = (通用RM + 专项RM + 规则检查) / 3
→ 单一漏洞无法同时骗过所有评判者
3. 人工监控(定期抽样)
→ 每N步采样100条检查
→ 发现欺骗模式后立即调整5. Qwen2.5:数据与后训练的突破
论文:Qwen2.5 Technical Report(arxiv:2412.15115)
5.1 模型系列
包含 base 和 instruct 的 0.5B、1.5B、3B、7B、14B、32B 和 72B 模型,MoE 模型 Qwen2.5-Turbo 和 Qwen2.5-Plus。
模型结构:SwiGLU + RoPE + QKV bias + RMSNorm + GQA + YaRN + DCA,与 Qwen2 一致。
5.2 预训练数据(18T tokens)
四大改进:
- 更精细的数据过滤:利用 Qwen2-Instruct 模型作为过滤器,多维度分析评估打分
- 更优的数学与代码数据:加入 Qwen2.5-Math 和 Qwen2.5-Coder 的训练数据
- 更高质量的合成数据:Qwen2-72B-Instruct + Qwen2-Math-72B-Instruct 合成,专有奖励模型严格过滤
- 更合理的数据混合:用 Qwen2-Instruct 对内容分类,对电商/社交媒体等过度代表领域下采样,对技术/科学等高价值领域上采样
5.3 长文本预训练(两阶段)
阶段一:使用 4K token 上下文长度训练,在最终预训练阶段将上下文从 4K 扩展到 32K token。
ABF 技术:将 RoPE 基础频率从 10000 提升到 1,000,000
# 原始 RoPE
θ_i = 10000 ^ (-2i/d)
# ABF
θ_i = 1000000 ^ (-2i/d)
# 底数变大 → θ_i 变小 → 旋转变慢 → 天然支持更长序列
# ABF vs NTK:
# NTK:推理时的补救措施(出门发现鞋小了,现场改)
# ABF:训练时的主动设计(出门前就买了合脚的鞋)Qwen2.5-Turbo 的四阶段扩展:32K → 64K → 128K → 256K → 1M token
每个阶段训练数据:40%当前最大长度序列 + 60%较短序列
应用 YaRN + DCA 使得 Qwen2.5-Turbo 处理最多 1M token
其他模型处理最多 128K token5.4 后训练(1M 示例数据)
涵盖 SFT、DPO 和 GRPO,共9大类:
能力扩展类
长序列生成:
问题:模型不会生成长文
解法:反向翻译技术
→ 从预训练语料里找优质长文
→ 让模型生成这篇长文的 query
→ (query, 长文) 配对,复用高质量长文
→ 确保输出长度符合预期数学推理:
引入 Qwen2.5-Math 中的 CoT 数据
拒绝采样保证高质量
结合奖励建模和带注解的答案
→ 帮助模型生成逐步推理过程编程能力:
整合 Qwen2.5-Coder 指令微调数据
多个编程语言的智能体协作
生成约40种编程语言的多样化高质量指令数据
多语言 sandbox 静态代码检查
自动化单元测试验证代码质量精准执行类
指令跟随:
模型既生成指令也生成相应的验证代码
配合全面的单元测试交叉验证
基于执行反馈的拒绝采样精选训练数据结构化数据理解:
包含传统任务(表格问答、事实验证、错误修正、结构理解)
和复杂结构化/半结构化数据任务
通过加入 CoT 增强从结构化数据中推理的能力逻辑推理:
引入来自多个领域的70000个新 query
涵盖多项选择题、判断题和开放性问题
演绎推理、归纳推理、类比推理等多种方式
迭代优化剔除错误答案和有缺陷的推理过程鲁棒性类
跨语言迁移:
翻译模型将高资源语言指令翻译为低资源语言
评估语义对齐情况
保证响应在不同语言间的逻辑结构和风格一致性鲁棒系统指令:
构建数百条通用系统提示词
同一问题配不同 system prompt 训练
→ 模型学会忽略 prompt 风格差异,专注任务本身响应过滤:
专门的评论模型 + 多智能体协作评分系统
只有被所有评分系统认为完美的响应才被保留
→ 保证输出的高质量标准6. Qwen3:推理与效率的融合
6.1 模型系列
从 0.6B 到 235B 参数量的多种模型(Dense 或 MoE)。
包含 Qwen3-235B-A22B、Qwen3-32B 等前沿模型,以及通过蒸馏得到的 Qwen3-14B/8B/4B 等轻量模型。
6.2 模型结构(相较 Qwen2 的变化)
Q/K RMSNorm(防止注意力坍缩)
Attention Collapse(注意力坍缩)问题:
训练后期 Q 和 K 的向量幅度差异极大
→ 某些头的点积值爆炸到几千
→ softmax 之后变成 one-hot 分布
→ 模型只关注一个 token,其他全部忽略
→ 注意力坍缩Qwen2 vs Qwen3 代码对比:
# Qwen2:直接使用,无归一化
query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
# Qwen3:先投影,再归一化
self.q_norm = Qwen3RMSNorm(self.head_dim) # 注意:在 head_dim 维度!
self.k_norm = Qwen3RMSNorm(self.head_dim)
query_states = self.q_norm(self.q_proj(hidden_states).view(hidden_shape)).transpose(1, 2)
key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2)为什么在 head_dim 而非 hidden_size 归一化:
每个头负责捕捉不同类型的关系:
Head 1 → 语法关系
Head 2 → 指代关系
Head 3 → 位置关系
头间的幅度差异本身有意义!
对整体 hidden_size 归一化 → 各头互相污染 → 多头意义丧失
对每个头单独归一化 → 防止各自坍缩,同时保留头间独立性 ✅Attention Bias 可配置
# Qwen2:QKV bias 写死为 True
self.q_proj = nn.Linear(..., bias=True)
# Qwen3:bias 变成可配置
self.q_proj = nn.Linear(..., bias=config.attention_bias)原因:不同规模的模型对 bias 的需求不同。大模型(235B)参数极度充裕,W 矩阵本身已能处理任何位置偏移,bias 是多余的,去掉可加速训练推理。小模型(0.6B)参数稀缺,bias 是宝贵的"兜底锚点"。
Sliding Window 判断逻辑移到初始化阶段
# Qwen2:检查逻辑在 forward 中(每次推理都判断)
def forward(self, ...):
sliding_window = None
if (self.config.use_sliding_window and ...):
sliding_window = self.config.sliding_window
# Qwen3:检查逻辑在 __init__ 中(只判断一次)
def __init__(self, config, layer_idx):
self.sliding_window = config.sliding_window
if not (self.config.use_sliding_window and ...):
self.sliding_window = None # 初始化时确定,forward 直接用6.3 预训练
三阶段预训练(训练数据从 Qwen2.5 的 18T 扩展到 36T tokens):
- 第一阶段:在超过 30T tokens 数据上预训练,上下文长度 4K tokens
- 第二阶段:增加知识密集型数据比例(STEM、代码、逻辑推理),额外训练 5T tokens,提升推理能力
- 第三阶段:使用高质量长上下文数据,扩展上下文长度至 32K tokens
6.4 后训练:四阶段流程
目标:同时具备"慢慢推理"和"快速响应"两种能力。
Stage 1:Long-CoT 冷启动
→ 使用多样化的长 CoT 数据微调
→ 涵盖数学、编码、逻辑推理、STEM
→ 赋予模型基本推理能力
Stage 2:基于推理的强化学习
→ 通过 RL 进一步提升推理能力
Stage 3:思考模式融合
→ 同时喂三种数据:
带<think>标记的长CoT数据
带/no_think标记的直接回答数据
无标记的自动判断数据(训练Auto模式)
→ 模型学会"看标记,切模式"
Stage 4:通用强化学习
→ 在超过20个领域任务上进行强化学习
→ 进一步优化两种模式的表现轻量模型:通过 Strong-to-Weak Distillation(强到弱蒸馏)训练。
蒸馏的本质优势(Dark Knowledge):
硬标签训练:
问:苹果是什么颜色?答:红色(只有0和1)
软标签蒸馏(大模型输出概率分布):
红色: 0.70, 绿色: 0.20, 黄色: 0.09, 紫色: 0.01
→ 小模型同时学到:"红色最对,但绿色也有道理"
→ 传递的是大模型对世界的"认知不确定性结构"
→ 不是答案,是暗知识(Dark Knowledge)思考模式的实际使用:
# 开启思考(/think 标记)
messages = [{"role": "user", "content": "证明勾股定理 /think"}]
# 输出:<think>让我逐步分析...</think>然后给出答案
# 关闭思考(/no_think 标记)
messages = [{"role": "user", "content": "今天几号 /no_think"}]
# 输出:直接回答
# Auto 模式(无标记,模型自判断)
messages = [{"role": "user", "content": "证明勾股定理"}]
# 模型内部判断复杂度,自动决定是否思考6.5 模型效果(Base 模型对比)
| Benchmark | Qwen2.5-72B | DeepSeek-V3 | Qwen3-235B |
|---|---|---|---|
| MMLU | 86.06 | 87.19 | 87.81 |
| MATH | 62.12 | 62.62 | 71.84 |
| GSM8K | 91.50 | 87.57 | 94.39 |
| EvalPlus | 65.93 | 63.75 | 77.60 |
| MBPP | 76.00 | 74.20 | 81.40 |
核心结论:Qwen3-235B(MoE,激活22B)在数学和代码上大幅领先,体现了 MoE 架构的参数效率优势。
7. Qwen3.5:迈向原生多模态智能体
发布时间:2026年2月
首发模型:Qwen3.5-397B-A17B(397B总参数,17B激活参数)
7.1 核心创新概览
| 技术 | 说明 |
|---|---|
| 混合注意力 | GatedDeltaNet (线性) + Gated Full Attention,75:25 交替 |
| MRoPE | 多模态旋转位置编码,3D位置 (temporal, height, width) |
| Gated Attention | Q 投影输出翻倍,一半做 query,一半做 sigmoid 门控 |
| MoE | 512 路由专家 + 共享专家 + sigmoid 门控 |
| (1+w) RMSNorm | weight 初始化为 0,前向计算 x * (1 + weight) |
7.2 架构演进背景:O(n²) 问题
Full Attention 的计算瓶颈:
计算量和 KV Cache 随序列长度 L 的关系为 O(L²)
应用场景从短对话演进到 100K+ token 长文档、1M+ token 代码库
O(L²) 不再可承受:
→ 显存墙:KV Cache 迅速占满显存,batch size 受限
→ 推理延迟:生成每个 token 的延迟线性增加
数字感受:
32K² = 1,024(单位)
256K² = 65,536(单位)
→ 序列扩大8倍,计算量扩大64倍!Qwen3.5 的吞吐量优势:
vs Qwen3-Max:
32K 上下文:吞吐量 8.6 倍
256K 上下文:吞吐量 19.0 倍
→ 序列越长,优势越大(理论预期的完美体现)7.3 混合层设计:75% Linear + 25% Full
层分配模式:
[L, L, L, F, L, L, L, F, ...] (full_attention_interval=4)
L = GatedDeltaNet(线性注意力)
F = Gated Full Attention(全注意力)为什么不全用线性注意力:
纯 Linear Attention 的硬伤:
大海捞针任务(100K token里找特定信息)
→ 线性注意力维护固定大小记忆矩阵 S
→ 久远的精确信息容易被覆盖
→ 精确检索能力不如 Full Attention
解法:
75% Linear → 承担粗粒度语义混合(省算力)
25% Full → 承担精确全局交互校正(保质量)KV Cache 显存分析:
Linear 层:维护固定大小递推状态 → O(1)
Full 层: KV Cache 随序列增长 → O(n)
整体:由 O(n) 主导,但系数只有 0.25
→ 相比纯 Full Attention 的 KV Cache 缩小到 1/47.4 GatedDeltaNet:线性注意力的核心
从线性注意力到 Delta Rule
普通线性注意力的问题:
维护记忆矩阵 S
简单叠加写入:S_t = S_{t-1} + v_t · k_t^T
问题:变量X=1 写入S,变量X=2 再写入S
→ S里同时存着 X=1 和 X=2 → 记忆干扰Delta Rule 的核心思想:写入前先擦除旧信息
关键问题:用 Q 还是 K 查旧值?
→ K 是"写操作的地址"(我是谁,我对应字典哪一页)
→ Q 是"读操作的查询"(我想找什么)
→ 写入前用 K 查旧值,读取时才用 Q
Delta Rule 公式:
S_t = S_{t-1} + k_t ⊗ [β_t · (v_t - S_{t-1}^T · k_t)]
分解:
S_{t-1}^T · k_t → 用K查出旧值(key查自己的存储位置)
v_t - S_{t-1}^T k_t → 计算delta(新值-旧值,只写增量)
β_t → 写入强度(学习率)
k_t ⊗ delta → 外积更新对应位置
类似数据库的 UPSERT 操作:精确覆盖,不留残影Gated DeltaNet:加入遗忘门
问题:话题切换时(量子力学→食谱),记忆矩阵S里还残留旧话题内容,相互干扰。
解法:数据依赖的遗忘门 α_t
完整公式:
S_t = α_t · S_{t-1} · (I - β_t k_t k_t^T) + β_t v_t k_t^T
各参数含义:
α_t ∈ (0,1) 遗忘门:话题转换时→0,快速清空无关记忆
β_t ∈ (0,1) 写入强度:控制新信息写入深度
(I-β_t k_t k_t^T) Householder变换:腾出旧空间防止信息重叠前向计算 6 步骤
Step1:输入投影(4条并行路径)
in_proj_qkv → Q/K/V
in_proj_z → 输出门控
in_proj_b → beta(写入强度)
in_proj_a → alpha(衰减系数)
Step2:因果卷积(Causal Conv1d,kernel_size=4)
QKV经过 depthwise 因果卷积 + SiLU
→ 融合前4个位置的局部上下文
→ 弥补线性注意力对局部模式感知弱的缺陷(借鉴自 Mamba)
Step3:门控参数计算
beta = sigmoid(b) 学习率 ∈ (0,1)
g = -exp(A_log) * softplus(a + dt_bias) 衰减系数 < 0
Step4:GQA 扩展(Linear Attention 也支持 GQA)
Step5:核心计算(两条路径)
prefill:chunk_gated_delta_rule(分块并行,chunk_size=64)
decode: recurrent_gated_delta_rule(逐token递推)
Step6:输出门控
output = RMSNormGated(attn_out, gate_z)
→ RMSNorm(x) * SiLU(gate_z)prefill 用分块并行的原因:
逐token递推:严格串行,每步依赖上一步S,GPU大量核心闲置
分块并行:1024个token切成16个chunk
→ chunk内部矩阵乘法并行计算
→ 串行部分只有16步(而不是1024步)
→ GPU利用率大幅提升,速度差达数十倍Qwen3.5 vs Qwen3Next 投影层差异
# Qwen3Next:2个合并投影(需要复杂的重排函数)
self.in_proj_qkvz = nn.Linear(hidden_size, key_dim*2 + value_dim*2)
self.in_proj_ba = nn.Linear(hidden_size, num_v_heads*2)
# Qwen3.5:4个独立投影(语义清晰,便于优化)
self.in_proj_qkv = nn.Linear(hidden_size, key_dim*2 + value_dim)
self.in_proj_z = nn.Linear(hidden_size, value_dim) # 输出门控
self.in_proj_b = nn.Linear(hidden_size, num_v_heads) # beta
self.in_proj_a = nn.Linear(hidden_size, num_v_heads) # alpha
# 删除了 fix_query_key_value_ordering 方法7.5 Gated Full Attention
Q 维度翻倍 + sigmoid 门控:
# Q投影维度翻倍
self.q_proj = nn.Linear(hidden_size, num_heads * head_dim * 2) # ×2!
# forward 中拆分
query_states, gate = torch.chunk(q_proj_output, 2, dim=-1)
# 标准注意力计算
attn_output = attention(query_states, key_states, value_states)
# 门控
attn_output = attn_output * torch.sigmoid(gate)参数量分析:
标准 MHA(32Q+32K+32V):96单位参数
Qwen3.5(Q翻倍+GQA 16:1):
Q: 32×2=64单位
K: 32/16=2单位
V: 32/16=2单位
总计: 68单位
→ GQA省掉的远比Q翻倍多出的多,整体参数量反而减少QK Norm(继承自Qwen3):
self.q_norm = Qwen3_5RMSNorm(self.head_dim) # 在 head_dim 维度
self.k_norm = Qwen3_5RMSNorm(self.head_dim)
# head_dim=256 时尤为重要,防止大 head_dim 下的数值爆炸Partial RoPE(仅 25% 维度):
partial_rotary_factor = 0.25
# head_dim=256,只有前 64 维参与 RoPE 旋转,剩下 192 维保持原始值
rotary_dim = 64 # 256 * 0.25
q_rot, q_pass = q[..., :64], q[..., 64:] # 64 / 192
q_embed = cat([rotate(q_rot), q_pass]) # 拼接回 256位置信息 vs 内容信息分工:
参与RoPE的64维(25%):专门携带位置信息
剩余192维(75%):完全不受位置编码干扰,专门携带语义内容
→ 两者职责分离,互不干扰
→ 更大的head_dim,更纯净的内容表达空间7.6 MRoPE:多模态旋转位置编码
从 1D 到 3D 位置编码:
文本token:1D位置(pos, 0, 0)
图像token:3D位置(frame, row, col)
视频token:3D位置(t, h, w)
position_ids 的 shape:(3, B, L)
分别对应 temporal(T)、height(H)、width(W)文本token的特殊处理:
# 文本token设置:
t = 序列位置(0,1,2,3...) # 保留1D顺序信息
h = 0 # 固定常数
w = 0 # 固定常数
# 效果:cos((0-0)θ) = cos(0) = 1
# → 所有文本token在h/w维度"相对位置完全相同"
# → h和w对文本token静默
# → 退化回标准1D RoPE频率分段(mrope_section):
mrope_section = [11, 11, 10] # 总和32对 = 64维旋转空间
# T占11对频率,H占11对频率,W占10对频率
# 排列方式:交错排列(非分块)
# 分块:[T,T,T...H,H,H...W,W,W](时空联合关系难学)
# 交错:[T,H,W,T,H,W,T,H,W...](每局部包含完整3D位置信息)Qwen3 vs Qwen3VL vs Qwen3.5 RoPE对比:
| 特性 | Qwen3 | Qwen3VL | Qwen3.5 |
|---|---|---|---|
| RoPE类型 | 标准1D | MRoPE 3D | MRoPE 3D |
| mrope_section | - | [24,20,20] | [11,11,10] |
| head_dim | 128 | 128 | 256 |
| partial_rotary_factor | 1.0 | 1.0 | 0.25 |
| RoPE有效维度 | 128 | 128 | 64 |
Qwen3.5 用更大的 head_dim 但更小的 rotary factor,使 RoPE 有效维度(64)反而比 Qwen3VL(128)小,意味着更多维度留给内容表示,位置信息更加"紧凑"。
7.7 (1+w) RMSNorm
对比标准 RMSNorm:
# 标准 RMSNorm(Qwen3)
weight = torch.ones(dim) # 初始化为1
output = normalize(x) * weight
# (1+w) RMSNorm(Qwen3.5,来自Gemma3)
weight = torch.zeros(dim) # 初始化为0
output = normalize(x) * (1 + weight)
# 初始状态:两者完全一样(都输出 normalize(x))
# 但训练动态不同!训练优势:
想"关闭"这一层:
标准:weight → 0(从1走到0,路径长)
(1+w):weight → -1(从0走到-1,梯度在0附近更稳定)
weight = -1 时:
normalize(x) * (1 + (-1)) = 0
→ 等效于残差连接跳过这层(自适应跳层)
→ 梯度直接"穿透",不在这里消失或爆炸
→ 60层网络如果20层自适应关闭,梯度只需穿越40层GatedRMSNorm(不同场景):
# 用在 GatedDeltaNet 的输出端
weight = torch.ones(hidden_size) # 注意:这里是 ones!
output = RMSNorm(x) * SiLU(gate_z)
# 为什么用 ones:
# 这个 Norm 需要在训练初期就能正常传递梯度
# 如果初始化0:SiLU(gate_z) * 0 = 0 → 输出全0 → 梯度消失 → 训练无法启动7.8 512 专家 MoE 架构
规格对比:
Qwen1.5-MoE: 60路由专家,每次激活4个,激活比例 6.7%
Qwen3.5-MoE: 512路由专家,每次激活10个 + 1共享专家,激活比例 2%TopK Router(softmax → topk(10) → renormalize):
router_logits = F.linear(hidden_states, self.weight) # [L, 512]
probs = F.softmax(router_logits, dim=-1) # 归一化到所有512专家
top_values, top_indices = torch.topk(probs, k=10) # 选top-10
top_values /= top_values.sum(dim=-1, keepdim=True) # renormalize
# 为什么 renormalize:
# softmax后10个专家权重之和≈0.35(只有35%信息量)
# renormalize后权重之和=1(信息量完整保留)细粒度专家(3D张量存储):
# 512个专家,每个是标准 SwiGLU 结构
self.gate_up_proj = nn.Parameter(
torch.empty(512, 2 * intermediate_dim, hidden_dim) # 3D张量
)
self.down_proj = nn.Parameter(
torch.empty(512, hidden_dim, intermediate_dim)
)
# 每个专家:output = down_proj(SiLU(gate_proj(x)) * up_proj(x))共享专家 + sigmoid 门控:
def forward(self, hidden_states):
# 路由专家
routing_weights, selected_experts = self.gate(hidden_states)
expert_output = self.experts(hidden_states, selected_experts, routing_weights)
# 共享专家(带sigmoid门控)
shared_output = self.shared_expert(hidden_states)
gate_value = F.sigmoid(self.shared_expert_gate(hidden_states))
shared_output = gate_value * shared_output
# 最终输出公式:
# output = Σ(w_i · expert_i(x)) + σ(g(x)) · shared(x)
return expert_output + shared_outputsigmoid 门控的作用:不同 token 对共享知识需求不同,gate 自适应调节共享专家贡献强度。
7.9 Early Fusion 多模态
后融合 vs 早期融合:
后融合(Qwen3VL旧方式):
图像 → ViT → Projector(信息瓶颈) → 注入LLM
→ 视觉信息被压缩后才进入LLM
→ 精确空间信息(按钮坐标)容易丢失
Early Fusion(Qwen3.5):
图像 → VisionModel → 视觉token
与文本token拼接 → 统一送入TextModel所有层
→ 视觉信号直接参与LLM深层计算
→ 精确到像素级的坐标信息保留
→ GUI 操作等 Agent 任务效果显著提升7.10 视觉编码器结构
完整处理流程:
输入:图像或视频帧
↓
PatchEmbed(Conv3d)
kernel_size = (temporal_patch_size, patch_size, patch_size)
图像(单帧):退化为2D卷积
视频(多帧):同时处理时序信息
→ 统一处理图像和视频,无需两套代码
↓
VisionBlocks × 27(标准ViT,Full Attention)
注:视觉部分用 Full Attention(图像patch需要精确全局交互)
↓
PatchMerger(4:1合并)
相邻4个patch合并成1个token
[4 × patch_dim] → MLP → [text_hidden_dim]
1024×1024图像:5000 patch → 1250 视觉token
↓
视觉token → 注入TextModel去除 DeepStack:
Qwen3VL 的 DeepStack:
在 ViT 第8、16、24层提取中间特征 → 多级 PatchMerger → 注入LLM
→ 多层级特征,类似FPN
→ 但参数量多,训练不稳定,序列长度膨胀
Qwen3.5 删除 DeepStack:
del self.deepstack_visual_indexes
del self.deepstack_merger_list
→ 直接跑完所有 VisionBlock,只用最终输出
原因:
Early Fusion + GatedDeltaNet 本身已能从不同深度感知视觉信息
DeepStack 的多层级功能被天然替代,不再需要"打补丁"7.11 DynamicCache 统一管理
混合架构的 Cache 挑战:
Full Attention 层:需要 key_cache + value_cache(随序列增长)
Linear Attention 层:需要 conv_states + recurrent_states(固定大小)
两套独立 Cache → 内存预分配复杂 + 与现有框架不兼容统一设计:
class Qwen3NextDynamicCache:
def __init__(self, config):
# 每层都初始化四个槽位
self.key_cache = [None] * num_layers # Full Attention 用
self.value_cache = [None] * num_layers # Full Attention 用
self.conv_states = [None] * num_layers # Linear Attention 用
self.recurrent_states = [None] * num_layers # Linear Attention 用
class Qwen3_5DynamicCache(Qwen3NextDynamicCache):
pass # 完全继承
# 运行时:
# Full Attention 层只用 key_cache/value_cache,其余为 None
# Linear Attention 层只用 conv_states/recurrent_states,其余为 None
# None 槽位不占实际显存工程优势:对外只有一个 Cache 对象,serving 系统无需感知两种状态的差异,无缝接入 vLLM 等现有框架。
7.12 Multi-Token Prediction (MTP)
标准 Next Token Prediction 的局限:
每次只预测下一个token
→ 每个训练步只产生1个预测信号
→ 大量计算只用来预测1个token,信息利用率偏低MTP 的核心思想:
同时预测未来N个token
→ 每个训练步产生N个预测信号
→ 同样计算量,N倍学习信号
→ 模型被迫学习全局语言结构(而非局部统计规律)
→ 在代码和数学任务上提升最明显工程实现(共享LM Head):
# 主干正常计算
hidden_states = transformer(input_ids)
# 预测头1(标准)
logits_1 = lm_head(hidden_states)
# 预测头2/3/4(轻量,共享lm_head)
delta_2 = small_mlp_2(hidden_states)
logits_2 = lm_head(hidden_states + delta_2) # 共享lm_head!
# 训练损失(权重递减)
loss = λ_1 * CE_1 + λ_2 * CE_2 + λ_3 * CE_3 + λ_4 * CE_4
# λ_1 > λ_2 > λ_3 > λ_4(近的预测更可靠,权重更高)推理时的投机采样收益:
训练时的MTP头可用于推理阶段的投机采样(Speculative Decoding):
Step1:用轻量MTP头快速生成4个候选token(草稿)
Step2:用主干模型一次性验证这4个token
结果处理:
→ 全部正确:1次forward = 4个token
→ 前2个正确,第3个错:接受前2个,从第3位重新生成
→ 平均:1次forward ≈ 2-3个token
对比标准自回归(1次forward=1个token):显著提速
工程联动:
MTP → 投机采样 → 异步RL加速(Rollout生成更快,Replay Queue填充更快)7.13 FP8 训练流水线
三层量化策略:
1. 激活量化:forward时激活值用FP8存储 → 激活显存降低约50%
2. MoE路由量化:路由矩阵计算用FP8 → 512专家路由显存大幅降低
3. GEMM量化:矩阵乘法(最耗时操作)用FP8 → H100的FP8 GEMM比BF16快约2倍敏感层保护机制(运行时监控):
# 每N步检测各层激活值的绝对最大值(amax)
amax = max(|activation|)
if amax > FP8_MAX_VALUE(448): # FP8 E4M3格式最大值
use_bf16_for_this_layer() # 自动升级到BF16
else:
keep_fp8()
# 高风险层(容易超过448):
# QK点积前、FFN第一个线性层输出、MoE路由logits、残差连接累加处
# 低风险层:RMSNorm之后、Embedding层整体效果:激活显存降低约50%,训练速度提升超过10%,稳定扩展至数万亿token。
7.14 异步 RL 框架
传统同步 RL 的问题:
生成样本 → 等待 → 计算奖励 → 等待 → 更新参数 → 循环
GPU 在"等待"期间完全空闲Actor-Learner 解耦架构:
Actor GPU:不断生成 rollout → 存入 Replay Queue
Learner GPU:不断消费 rollout,计算梯度更新参数
→ 两者并行运行,互不等待
→ GPU 利用率最大化
→ 端到端加速 3x-5x关键技术细节:
Staleness Control(新鲜度控制):
→ Actor 用的参数最多落后 Learner 2步
→ 太旧的样本直接丢弃(staleness ≤ 2)
→ 保证 off-policy 偏差可控
Rollout 路由回放:
→ 相同任务的 rollout 路由给同一GPU
→ 减少跨卡通信,提升缓存命中率
投机采样(联动MTP):
→ 用MTP头加速 Rollout 生成
→ Replay Queue 填充更快
→ Learner 等待时间更短7.15 三种推理模式
Qwen3 的旧方式:在输入文本里加 /think、/no_think 标记(工程不够健壮)
Qwen3.5 的接口参数控制:
# thinking 模式(深度思考)
response = model.generate(messages, thinking_mode="thinking")
# 输出:<think>详细推理过程...</think>最终答案
# fast 模式(直接回答)
response = model.generate(messages, thinking_mode="fast")
# 输出:直接回答,无思考过程
# auto 模式(自适应)
response = model.generate(messages, thinking_mode="auto")
# 简单问题→fast,复杂问题→thinking,模型自判断7.16 规格参数
| 维度 | 数值 |
|---|---|
| 总参数量 | 397B |
| 激活参数量 | 17B |
| 模态 | 文本+图像+视频输入,文本输出 |
| 词表大小 | 248320(覆盖201种语言/方言) |
| 层数 | 60(15组,每组3L+1F) |
| 隐藏维度 | 4096 |
| head_dim | 256 |
| partial_rotary_factor | 0.25(RoPE维度64) |
| 原生上下文 | 262144 tokens |
| 可扩展上下文 | 最高约1010000 tokens(YaRN RoPE scaling) |
| FFN(MoE) | 512路由专家,每token激活10+1个 |
| MoE专家中间维度 | 1024 |
| GQA(Full Attn) | Q头32,KV头2(16:1) |
7.17 RL Environment Scaling
官方核心结论:
训练环境数量从 0 → 17500:
Qwen3.5 Thinking:排名从13 → 4(超越 Claude Opus 4.5 Thinking)
Qwen3.5 Non-Thinking:排名从13 → 7(超越 DeepSeek-V3.2 Thinking)
规律:
1. 环境越多,性能越强(RL在Agent任务上的Scaling Law得到验证)
2. Thinking 模式始终优于 Non-Thinking,但差距随环境增多缩小
3. 官方策略:"更强调RL环境的难度与可泛化性,而非针对特定指标优化"
→ 防止 Benchmark Hacking,追求真实泛化能力8. 横向对比与关键演进主线
8.1 Qwen3 vs Qwen3.5 核心差异
| 特性 | Qwen3 | Qwen3.5 |
|---|---|---|
| 注意力类型 | Full + Sliding Window | Hybrid(Linear 75% + Full 25%) |
| 推理复杂度 | O(n²) | 大部分O(n),少量O(n²) |
| 长序列友好 | 有限(靠SWA缓解) | 原生高效(Linear Attention) |
| GQA比例 | 32:32(MHA) | 16:2(MoE变体) |
| head_dim | 128 | 256 |
| RoPE类型 | 标准1D,全维度 | MRoPE 3D,仅25%维度 |
| RMSNorm | 标准(ones初始化) | (1+w)变体(zeros初始化) |
| 视觉编码器 | 无 | ViT(去掉DeepStack) |
8.2 完整继承链(Qwen3.5)
Qwen3_5TextConfig → Qwen3NextConfig
Qwen3_5GatedDeltaNet → Qwen3NextGatedDeltaNet
Qwen3_5Attention → Qwen3NextAttention → Qwen3MoeAttention → Qwen3Attention
Qwen3_5RMSNorm → Qwen3NextRMSNorm → Gemma3RMSNorm
Qwen3_5TextModel → Qwen3NextModel
Qwen3_5Model → Qwen3VLModel
Qwen3_5DynamicCache → Qwen3NextDynamicCache
Qwen3_5MoeSparseMoeBlock → Qwen3NextSparseMoeBlock → Qwen2MoeSparseMoeBlock
Qwen3_5MoeForCausalLM → Qwen3NextForCausalLM → MixtralForCausalLM
文本骨干:来自 Qwen3Next(混合注意力架构)
多模态外壳:来自 Qwen3VL(VisionModel + MRoPE)
MoE 机制:追溯到 Qwen2Moe 和 Mixtral
RMSNorm 设计:来自 Gemma38.3 核心技术决策总结
- 混合注意力是核心:75% O(n) + 25% O(n²),在保持表达力的同时大幅提升长序列效率
- 投影层拆分是实用性改进:4个独立投影替代2个合并投影,代码更清晰,实现更灵活
- 去 DeepStack 是简化之举:混合注意力的多尺度建模能力已足够,无需多级特征注入
- (1+w) RMSNorm 贯穿全局:从 Gemma3 借鉴,为训练稳定性做出贡献
- Early Fusion 是多模态的未来:信息不再经过瓶颈,视觉信号直接参与深层计算
笔记整理完毕,覆盖 Qwen1 至 Qwen3.5 全系列核心技术。