【LLM】qwen3.5-9b

📅 2026/7/8 2:43:39 👁️ 阅读次数 📝 编程学习
【LLM】qwen3.5-9b

一、总体架构(三大子系统)

Qwen3_5ForConditionalGeneration │ ┌───────────────────────────┼───────────────────────────┐ ▼ ▼ ▼ Qwen3_5VisionModel Qwen3_5TextModel (Backbone) LM Head (ViT 视觉编码器) (32 层 hybrid decoder) (投影到 vocab) depth=27 blocks full+linear attention tie_word_embed hidden=1152 hidden=4096 patch=16 heads=16

输入数据流

文本 tokens ──┐ │──► 词嵌入 embed_tokens (hidden=4096) ──┐ <image_pad> ──┘ │ ▼ Reference ──► Qwen3_5VisionModel (ViT) ──► out (4096d) Images / Video ├─ Conv3d patch_embed ├─ pos_embed (bilinear interp) ├─ 27 × VisionBlock (full attention) └─ PatchMerger (spatial_merge=2 → 4× 压缩) │ [文本 embed | 视觉 embed replaces <image_pad>] ◄──┘ │ ▼ Qwen3_5TextModel 32 × DecoderLayer (mixture of full & linear attention) │ ▼ RMSNorm → LM head

关键点:视觉侧和文本侧的融合发生在嵌入层,不是 cross-attention。视觉 tokens 被投影到 4096 维后,替换文本序列里的<image_pad>占位 token,之后统一走文本 backbone 的 self-attention。


二、Vision Tower(视觉编码器)细节

Qwen3_5VisionModelmodeling_qwen3_5.pyL1018-1125):

组件结构输出
patch_embedConv3d(3, 1152, kernel=(2,16,16), stride=(2,16,16))(T/2, H/16, W/16) 网格,每 patch 1152d
pos_embed双线性插值的可学习 2D 位置编码 (num_position_embeddings=2304 → 48×48)加到 patch embed 上
rotary_pos_emb2D RoPE,每 head_dim/2 = 36 维送 attention
blocks27 ×Qwen3_5VisionBlock
每块含Qwen3_5VisionAttentionfull attention,16 heads,head_dim=72)+ MLP(GELU,4304 中间维)
(N_patch, 1152)
merger空间 2×2 池化 →LayerNorm → Linear(4608, 4608) → GELU → Linear(4608, 4096)(N_patch/4,4096)

参数量估算

  • Conv3d patch_embed:~1.8M
  • 27 层 vision block:每层 ≈ 15M,合计~405M
  • pos_embed:2304 × 1152 ≈ 2.6M
  • merger:≈ 39M

Vision tower 合计≈ 450M(占 9B 里的约 5%)。

核心事实spatial_merge_size=2temporal_patch_size=2→ 一张 448×448 图像会得到约(448/16/2)² = 196个视觉 token(送进文本 backbone 时)。视频每 2 帧合并一次时间。


三、Text Backbone(文本主干)——hybrid attention 是核心

Qwen3_5TextModelmodeling_qwen3_5.pyL1137):

input: [B, T, 4096] │ ├─ DecoderLayer 0 (linear_attention) ├─ DecoderLayer 1 (linear_attention) ├─ DecoderLayer 2 (linear_attention) ├─ DecoderLayer 3 (full_attention) ← 只有这 8 层能拿到标准 attention weights ├─ DecoderLayer 4 (linear_attention) ├─ DecoderLayer 5 (linear_attention) ├─ DecoderLayer 6 (linear_attention) ├─ DecoderLayer 7 (full_attention) ← ├─ ... ├─ DecoderLayer 31 (full_attention) ← │ └─ RMSNorm → hidden_states

Full attention 层的位置full_attention_interval=4,从第 3 层开始):

[3, 7, 11, 15, 19, 23, 27, 31] 共 8 层

其余24 层都是linear_attentionQwen3_5GatedDeltaNet,一种 state-space 类似 Mamba 的机制)。

3.1 Full Attention 层(Qwen3_5Attention

标准多头 self-attention:

  • hidden_size = 4096
  • num_attention_heads = 16
  • head_dim = 256(注意:这里不是 4096/16=256,是显式配置的)
  • 每 token 前向:Q, K, V ∈ [T, 16, 256]
  • Attention weights 矩阵:[16, T, T]
  • 输出:(hidden_states, attention_weights)

这是我们能提取到 attention weight 的唯一入口

3.2 Linear Attention 层(Qwen3_5GatedDeltaNet

不是标准 QK^T 结构,而是状态空间模型——用 recurrent 累加的方式近似 attention,形式类似 Mamba / RetNet。特征:

  • 显存 O(hidden × head_dim),与序列长度无关
  • 没有明确的 attention weights 矩阵(数学上没有 softmax(QK^T))
  • HuggingFace 里output_attentions=True静默丢弃这些层的返回值

这就是为什么我实验里out.attentions长度只有 8——只有 full_attention 层能提供 attention weights。

3.3 Decoder Layer 前向(Qwen3_5DecoderLayer.forward

residual=hidden_states hidden_states=input_layernorm(hidden_states)# RMSNormiflayer_type=="linear_attention":hidden_states=linear_attn(hidden_states,...)# SSM-styleeliflayer_type=="full_attention":hidden_states,_=self_attn(hidden_states,...)# 标准 attentionhidden_states=residual+hidden_states# residualresidual=hidden_states hidden_states=post_attention_layernorm(hidden_states)hidden_states=mlp(hidden_states)# SwiGLU MLPhidden_states=residual+hidden_states# residual

单层参数:

  • attention (full):Q/K/V/O projection 各 ~4M,合计 ~16M;linear_attention 大致同量级
  • MLP:Linear(4096, 12288) + Linear(12288, 4096)= 50M(3 个 gate 结构,实际约150M
  • 每层合计约170M,32 层 =~5.4B

四、总参数量核对

组件参数量
Vision tower(27 层 ViT)~450M
Text embed_tokens (248320 × 4096)~1.0B
Text backbone (32 层)~5.4B
LM head (tied with embed_tokens)0(复用)
RMSNorm 等~1M
总计~7B ~ 9B(含 embedding 后是 9B)

配置里的 “9B” 主要来自巨大的 vocabulary embedding(248K token)。