7.6 Qwen3.5:线性注意力混合体
前面几节已经分别展示了纯全局注意力架构(Llama、Qwen3)和滑动窗口混合架构(Gemma 3)。它们的共同点是:不论局部还是全局,注意力矩阵的计算始终遵循 Softmax 范式,复杂度对序列长度保持
本节将以 Qwen3.5-0.8B 为对象,剖析其混合架构的设计哲学,逐一拆解线性注意力层与全局注意力层的实现差异,最后讨论这一架构趋势的更广泛意义。

图 7-21:Qwen3.5-0.8B 的混合注意力架构。24 层中 18 层使用 DeltaNet 线性注意力、6 层使用全局 Softmax 注意力,按 3:1 比例交替排列。
7.6.1 架构总览:0.8B 参数的混合布局
Qwen3.5-0.8B 的完整配置如下:
| 超参数 | 值 | 说明 |
|---|---|---|
vocab_size | 248,320 | 词表大小 |
context_length | 262,144 | 最大上下文长度(256K) |
emb_dim | 1,024 | 嵌入维度 |
n_layers | 24 | Transformer 层数 |
n_heads | 8 | 全局注意力层的查询头数 |
n_kv_groups | 2 | 全局注意力层的 KV 组数 |
head_dim | 256 | 全局注意力层的每头维度 |
hidden_dim | 3,584 | FFN 中间维度 |
rope_base | 10,000,000 | RoPE 基频( |
partial_rotary_factor | 0.25 | RoPE 部分旋转因子 |
linear_num_value_heads | 16 | 线性注意力层的 Value 头数 |
linear_num_key_heads | 16 | 线性注意力层的 Key 头数 |
linear_key_head_dim | 128 | 线性注意力层的 Key 头维度 |
linear_value_head_dim | 128 | 线性注意力层的 Value 头维度 |
linear_conv_kernel_dim | 4 | 线性注意力层的因果卷积核大小 |
24 层 Transformer 按以下固定模式排列:
层 0: linear_attention 层 12: linear_attention
层 1: linear_attention 层 13: linear_attention
层 2: linear_attention 层 14: linear_attention
层 3: full_attention ← 层 15: full_attention ←
层 4: linear_attention 层 16: linear_attention
层 5: linear_attention 层 17: linear_attention
层 6: linear_attention 层 18: linear_attention
层 7: full_attention ← 层 19: full_attention ←
层 8: linear_attention 层 20: linear_attention
层 9: linear_attention 层 21: linear_attention
层 10: linear_attention 层 22: linear_attention
层 11: full_attention ← 层 23: full_attention ←24 层中有 18 层线性注意力、6 层全局注意力,比例为 3:1——每 4 层为一个周期,前 3 层使用 DeltaNet 线性注意力,第 4 层使用标准 Softmax 全局注意力。
几个关键设计选择值得注意:
独立的 head_dim 与部分旋转。 全局注意力层的 head_dim=256 远大于 emb_dim / n_heads = 128,但 RoPE 仅作用于其中 25%(partial_rotary_factor=0.25),即 64 个维度参与旋转,其余 192 个维度直接通过。这种"部分旋转"策略与 Gemma 3 的做法异曲同工:大 head_dim 赋予每个头更强的表达能力,而部分旋转避免了对所有维度施加位置编码的约束。
线性注意力层使用不同的头配置。 线性注意力层有 16 个 Key/Value 头、每头维度 128,与全局注意力层的 8 个查询头、head_dim=256 完全不同。这种异构设计是因为两类注意力机制对参数的使用方式截然不同:全局注意力依赖大维度 Q/K 内积来精确匹配远程 token,线性注意力则通过状态矩阵的递推更新来压缩历史信息——更多但更小的头有利于状态矩阵维护多条独立的"记忆通道"。
Weight Tying。 输入嵌入层与输出投影层共享权重。模型总参数约 10.1 亿,其中嵌入矩阵占
7.6.2 两种注意力层的实现
Qwen3.5 的核心创新在于让两种计算范式——Softmax 注意力和线性注意力——共存于同一个模型中。两者共享相同的 RMSNorm、SwiGLU FFN 和残差连接结构,仅在"token mixing"模块上有本质区别。
全局注意力层:门控查询投影。 Qwen3.5 的全局注意力层在标准 GQA 的基础上增加了一个门控机制——Query 投影的输出维度是标准值的 2 倍,一半作为 Query,另一半作为门控信号:
class GroupedQueryAttention(nn.Module):
def __init__(self, d_in, num_heads, num_kv_groups, head_dim):
super().__init__()
self.d_out = num_heads * head_dim
# Query 投影输出 2 倍维度:一半 Query,一半 Gate
self.W_query = nn.Linear(d_in, self.d_out * 2, bias=False)
self.W_key = nn.Linear(d_in, num_kv_groups * head_dim, bias=False)
self.W_value = nn.Linear(d_in, num_kv_groups * head_dim, bias=False)
self.out_proj = nn.Linear(self.d_out, d_in, bias=False)
def forward(self, x, mask, cos, sin):
b, num_tokens, _ = x.shape
# 分离 Query 和 Gate
q_and_gate = self.W_query(x)
q_and_gate = q_and_gate.view(b, num_tokens, self.num_heads, self.head_dim * 2)
queries, gate = torch.chunk(q_and_gate, 2, dim=-1)
gate = gate.reshape(b, num_tokens, self.d_out)
# 标准 GQA 流程:QKNorm → RoPE → 注意力计算
keys = self.W_key(x)
values = self.W_value(x)
# ... (QKNorm, RoPE, 注意力矩阵计算) ...
context = (attn_weights @ values).transpose(1, 2).reshape(b, num_tokens, self.d_out)
# 门控:Sigmoid(gate) 逐元素缩放注意力输出
context = context * torch.sigmoid(gate)
return self.out_proj(context)门控查询投影的作用是让模型能够逐元素地调节注意力输出的强度。直观理解:Query 的一半负责"从哪里读取信息",另一半负责"读到的信息保留多少"。这种设计在 Mamba-2 和 Griffin 等混合架构中已有先例,核心动机是当全局注意力层数量较少时,每一层需要承担更精细的信息筛选任务——门控机制赋予了这一能力。
线性注意力层:Gated DeltaNet。 线性注意力层采用 Gated DeltaNet(详见 §6.6),其核心递推公式为:
其中
- 因果卷积前置。 QKV 投影后、进入递推之前,先通过一个核大小为 4 的深度可分离因果卷积(depthwise causal Conv1d),对局部相邻 token 进行短程混合。这一步的作用类似于 Mamba 中的因果卷积——弥补线性注意力在极短距离依赖上的不足:
self.conv1d = nn.Conv1d(
in_channels=conv_dim, # key_dim * 2 + value_dim
out_channels=conv_dim,
kernel_size=4, # 仅看前 4 个 token
groups=conv_dim, # 深度可分离:每个通道独立卷积
padding=3, # 因果填充
bias=False,
)L2 归一化替代 QKNorm。 线性注意力层在递推计算前对 Query 和 Key 做 L2 归一化(而非全局注意力层的 RMSNorm)。L2 归一化将向量缩放到单位球面,确保状态矩阵
中的外积更新不会因为 Q/K 范数爆炸而导致数值不稳定。 门控 RMSNorm 输出。 线性注意力层的输出先经过一个门控 RMSNorm:
,其中 是输入 经过独立线性投影得到的门控信号。这与全局注意力层的 Sigmoid 门控不同——SiLU 允许负值通过(虽然幅度很小),有助于梯度流动。
TransformerBlock:按层类型分发。 与 Gemma 3 的混合注意力类似,Qwen3.5 通过一个 layer_type 标志在初始化时决定每层使用哪种 token mixing 模块:
class TransformerBlock(nn.Module):
def __init__(self, cfg, layer_type, layer_idx):
super().__init__()
self.layer_type = layer_type
if layer_type == "full_attention":
self.token_mixer = GroupedQueryAttention(...)
elif layer_type == "linear_attention":
self.token_mixer = Qwen3_5GatedDeltaNet(cfg, layer_idx)
self.ff = FeedForward(cfg) # SwiGLU,所有层共享
self.norm1 = RMSNorm(cfg["emb_dim"])
self.norm2 = RMSNorm(cfg["emb_dim"])
def forward(self, x, mask, cos, sin):
shortcut = x
x = self.norm1(x)
if self.layer_type == "full_attention":
x = self.token_mixer(x, mask, cos, sin)
else:
x = self.token_mixer(x) # 线性注意力不需要掩码和 RoPE
x = x + shortcut
shortcut = x
x = self.norm2(x)
x = self.ff(x)
x = x + shortcut
return x一个重要的实现细节:线性注意力层不接收掩码和 RoPE 参数。这是因为 DeltaNet 的递推天然是因果的——每步只依赖之前的状态,无需显式因果掩码;同时,递推状态的更新方式已隐含了位置信息的编码,不依赖 RoPE。
7.6.3 零偏心 RMSNorm
Qwen3.5 延续了 Gemma 3 引入的零中心参数化 RMSNorm——权重初始化为零向量,前向传播时使用
class RMSNorm(nn.Module):
def __init__(self, emb_dim, eps=1e-6):
super().__init__()
self.eps = eps
self.weight = nn.Parameter(torch.zeros(emb_dim)) # 初始化为 0
def forward(self, x):
x_norm = x.float() * torch.rsqrt(
x.float().pow(2).mean(dim=-1, keepdim=True) + self.eps
)
return (x_norm * (1.0 + self.weight.float())).to(x.dtype)这与 Qwen3 使用的标准 RMSNorm(权重初始化为 1,直接乘以
7.6.4 为什么是线性+全局混合?

图 7-22:线性注意力的状态矩阵递推过程。固定大小的状态矩阵通过门控遗忘和增量更新压缩全部历史信息,实现对序列长度线性的推理复杂度。
Gemma 3 的 5:1 滑动窗口+全局混合已经证明了"不是所有层都需要全局注意力"这一直觉。Qwen3.5 将这一思路推进了一步:不是所有层都需要 Softmax 注意力。两种混合策略的对比如下:
| 维度 | Gemma 3(SWA + Full) | Qwen3.5(DeltaNet + Full) |
|---|---|---|
| 局部层机制 | 滑动窗口 Softmax | DeltaNet 线性递推 |
| 局部层复杂度 | ||
| 局部层 KV 缓存 | 保留最近 | 固定 |
| 全局层作用 | 跨窗口信息整合 | 精确远程检索 |
| 混合比例 | 5:1 | 3:1 |
| 位置编码 | 双 RoPE 基频 | 全局层使用 RoPE,线性层不使用 |
两种策略背后有一个共同的认知:大部分 Transformer 层在处理文本时,注意力权重高度集中在局部区域。既然如此,为这些层配备完整的
滑动窗口方案(Gemma 3)保留了 Softmax 的精确匹配能力,但将视野限制在固定窗口内。优势是实现简单(只需修改掩码),劣势是窗口外的信息完全不可见——即使是窗口边界附近的强依赖也会被截断。
线性注意力方案(Qwen3.5)用状态矩阵取代显式的 token-to-token 注意力矩阵。优势是理论上能通过递推将任意远的信息压缩进状态中,没有硬性的窗口截断;劣势是状态矩阵容量有限(
),对远程精确检索的能力弱于 Softmax——当需要精确回忆某个特定 token 的内容时,DeltaNet 的表现不如全局注意力。
这正是混合架构的设计逻辑:线性注意力层负责高效处理局部模式和渐进式的上下文压缩,全局注意力层负责需要精确匹配的远程信息检索。两类层各司其职、优势互补。
7.6.5 效率分析
计算复杂度。 在 Qwen3.5-0.8B 的 24 层中,18 层线性注意力的复杂度为
相比 24 层全部使用全局注意力的
KV 缓存。 全局注意力层的 KV 缓存随序列长度线性增长,但仅有 6 层需要存储完整的 KV 历史。线性注意力层不需要 KV 缓存——它们通过固定大小的状态矩阵
- 6 层全局注意力的 KV 缓存:
(2 个 KV 组、head_dim 256、KV 各一份、BF16 每元素 2 字节) - 18 层线性注意力的状态:
(16 个头、 状态矩阵、BF16)
KV 缓存总量约 393 MB,远低于 24 层全局注意力所需的约 1.5 GB。更重要的是,线性注意力层的状态大小与序列长度完全无关——无论输入 4K 还是 256K token,18 层线性层的内存占用恒定为 9.4 MB。
推理性能。 在 Nvidia A100 GPU 上,Qwen3.5-0.8B 以 BF16 精度运行时显存占用约 2.54 GB(含模型权重和 KV 缓存),生成速度约 8-9 tokens/sec(无 KV 缓存优化的基础模式)。模型的 float32 理论内存为 7.63 GB,BF16 为 3.81 GB。
7.6.6 混合注意力的趋势
Qwen3.5 并非孤例。2025 年以来,多个主流模型相继采用了线性注意力与全局注意力的混合架构:
| 模型 | 线性注意力机制 | 全局注意力比例 | 总参数量 |
|---|---|---|---|
| Qwen3.5-0.8B | Gated DeltaNet | 25%(6/24 层) | 0.8B |
| Kimi Linear | Gated DeltaNet | 约 20% | 未公开 |
| Zamba-2 | Mamba-2 | 约 17% | 7B |
| Falcon-H1 | Mamba-2 | 约 25% | 1.5B–34B |
这些模型的共同模式是:线性注意力层处理大部分局部、渐进式的上下文压缩任务,少量全局注意力层定期"刷新"模型对完整上下文的精确记忆。线性层与全局层的比例通常在 3:1 到 5:1 之间,过多全局层会削弱效率优势,过少则会导致远程信息丢失。
这一趋势的技术驱动力是明确的:随着上下文窗口从 4K 扩展到 128K 乃至 1M,纯 Softmax 注意力的

图 7-23:Gated DeltaNet 线性注意力的递推机制。通过固定大小的状态矩阵压缩历史信息,实现对序列长度线性的计算复杂度。
本节小结
本节以 Qwen3.5-0.8B 为案例,剖析了线性注意力与全局注意力混合架构的设计与实现:
- 混合架构布局:24 层中 18 层使用 Gated DeltaNet 线性注意力、6 层使用标准 Softmax 全局注意力,按 3:1 比例交替排列(每 4 层一个周期)。两类层共享 SwiGLU FFN 和零中心 RMSNorm,仅在 token mixing 模块上有本质区别。
- 全局注意力层的创新:引入门控查询投影(Query 投影输出 2 倍维度,一半作 Query、一半作 Sigmoid 门控),使少量全局层具备更精细的信息筛选能力。使用 GQA(8 头 / 2 KV 组)、QKNorm、部分 RoPE(仅 25% 维度旋转)。
- 线性注意力层的实现:采用 Gated DeltaNet 递推机制,前置因果卷积(核大小 4)处理极短距离依赖,L2 归一化 Q/K,门控 RMSNorm + SiLU 输出。不需要因果掩码和 RoPE。
- 效率优势:线性层的状态矩阵大小固定(
,与序列长度无关),18 层线性注意力的状态仅占约 9.4 MB(BF16),全局注意力的 KV 缓存降至 6 层。在 256K 上下文下,全局注意力计算量降至纯 Softmax 架构的 25%。 - 设计哲学:线性注意力层负责高效的局部模式处理和渐进式上下文压缩,全局注意力层负责精确的远程信息检索。两类层各司其职,是当前超长上下文模型在
瓶颈与精确检索需求之间的工程最优折中。