微调LLM前你需要了解的一些概念-- 基于 Qwen3 配置文件的实践

本文基于如下 Qwen3 配置文件进行讲解:

{ "architectures": [ "Qwen3ForSequenceClassification" ], "attention_bias": false, "attention_dropout": 0.0, "bos_token_id": 151643, "dtype": "bfloat16", "eos_token_id": 151645, "head_dim": 128, "hidden_act": "silu", "hidden_size": 1024, "id2label": { "2": 68, "3": 99, "5": 158, "8": 239, xxx }, "initializer_range": 0.02, "intermediate_size": 3072, "label2id": { "0": "10197", "1": "102", "10": "1168", xxx }, "layer_types": [ "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention", "full_attention" ], "max_position_embeddings": 40960, "max_window_layers": 28, "model_type": "qwen3", "num_attention_heads": 16, "num_hidden_layers": 28, "num_key_value_heads": 8, "pad_token_id": 151643, "rms_norm_eps": 1e-06, "rope_parameters": { "rope_theta": 1000000, "rope_type": "default" }, "sliding_window": null, "tie_word_embeddings": true, "transformers_version": "5.3.0", "use_cache": true, "use_sliding_window": false, "vocab_size": 151669 }

目标是把前面学习过的 Transformer、QKV、多头注意力、MLP、输出层、分类头等概念,和一个真实模型配置对应起来,做到“知道概念,也看得懂工程配置”。

1. 这个配置文件描述的是什么模型

配置里最关键的一项是:

"architectures": [ "Qwen3ForSequenceClassification" ]

这说明它不是普通的文本生成模型,而是一个序列分类模型:

Qwen3 Transformer 主干 + Sequence Classification 分类头

结合目录名:

oncall_tenant_predict

可以推断它的任务大概率是:

输入一段 oncall / 告警 / 问题描述文本,预测它应该归属到哪个 tenant、团队或业务标签。

所以它和普通生成式 LLM 的区别在最后一层。

普通生成模型:

输入文本 → Transformer → 词表输出层 W_out → vocab logits → softmax → 下一个 token

这个序列分类模型:

输入文本 → Transformer → 分类头 → class logits → softmax → tenant 类别

也就是说:

Transformer 主干认知是一样的,但最后任务头不同。

2. 配置文件里的关键参数

从配置中抽出和模型结构最相关的字段:

{ "model_type": "qwen3", "hidden_size": 1024, "num_hidden_layers": 28, "num_attention_heads": 16, "num_key_value_heads": 8, "head_dim": 128, "intermediate_size": 3072, "hidden_act": "silu", "vocab_size": 151669, "max_position_embeddings": 40960, "rms_norm_eps": 1e-6, "attention_dropout": 0.0, "dtype": "bfloat16", "tie_word_embeddings": true, "use_cache": true }

对应成人话:

配置字段含义
model_type = qwen3使用 Qwen3 架构
hidden_size = 1024每个 token 的主干 hidden state 是 1024 维
num_hidden_layers = 28有 28 层 Transformer Block
num_attention_heads = 16每层有 16 个 Query attention heads
num_key_value_heads = 8每层有 8 个 Key/Value heads,说明使用 GQA
head_dim = 128每个 attention head 的维度是 128
intermediate_size = 3072MLP 中间层升维到 3072
hidden_act = siluMLP 使用 SiLU 激活函数
vocab_size = 151669tokenizer 词表大小
max_position_embeddings = 40960最大上下文长度约 40960 token
rms_norm_eps = 1e-6RMSNorm 的数值稳定参数
dtype = bfloat16使用 bf16 数值格式
use_cache = true推理时可使用 KV Cache

整体结构可以概括为:

Token IDs → Embedding → 28 层 Qwen3 Transformer Blocks → 序列级 hidden state → 分类头 → tenant logits → softmax → tenant 预测结果

图示如下:

oncall 文本

Tokenizer

Token IDs

Embedding: vocab_size x hidden_size

28 层 Transformer Blocks

序列级 hidden state

Classification Head

268 个类别 logits

softmax

tenant / 业务标签

3. 28 层 Transformer Block 对应什么

配置:

"num_hidden_layers": 28

表示模型有 28 个 Transformer Block 串行堆叠。

也就是:

X0 = Embedding(tokens) X1 = Block1(X0) X2 = Block2(X1) ... X28 = Block28(X27)

每一层的输出都会作为下一层输入。

一个典型 Decoder-only Transformer Block 大致包含:

RMSNorm → Multi-Head / Grouped Query Attention → 残差相加 → RMSNorm → MLP / FFN → 残差相加

图示:

输入 x

RMSNorm

Attention / GQA

残差相加 x + Attention(...)

RMSNorm

MLP / FFN

残差相加 x' + MLP(...)

输出 y,传给下一层

对应到 oncall tenant 预测任务:

低层:识别 token、服务名、错误码、局部短语 中层:理解报警、调用关系、错误上下文、业务实体 高层:形成更适合 tenant 分类的语义表示

这不是人工规定,而是帮助理解的直觉。

4. hidden_size = 1024:每个 token 的向量维度

配置:

"hidden_size": 1024

表示在 Transformer 主干里,每个 token 通常用一个 1024 维向量表示。

例如输入:

service A 在集群 X 出现大量 timeout

被 tokenizer 切成 token 后,每个 token 都会映射成类似这样的向量:

token_i → [0.12, -0.08, 0.31, ..., 0.05] # 1024 维

随着 28 层 Transformer 不断加工,这个向量会从“基础 token 表示”逐渐变成“融合上下文后的语义表示”。

5. Multi-Head Attention 在这个配置里如何落地

配置:

"num_attention_heads": 16, "head_dim": 128

表示每一层有 16 个 Query attention heads,每个 head 是 128 维。

因此 Query 侧的 attention 展开维度是:

16 × 128 = 2048

注意这里有一个实践细节:

hidden_size = 1024 num_attention_heads × head_dim = 2048

二者不相等。

这说明在该 Qwen3 配置中,attention 内部的 Q 投影维度可以和主干 hidden size 不完全一致。

可以粗略理解为:

主干 token 表示:1024 维 Q 投影后:16 个 head × 128 = 2048 维 Attention 计算后:再通过输出投影 Wo 回到 1024 维

也就是:

X: [batch, seq_len, 1024] Q = X Wq Q: [batch, seq_len, 2048] reshape Q: [batch, 16, seq_len, 128]

每个 Query head 会从一个角度理解上下文,比如:

Head 1:关注服务名和 PSM Head 2:关注错误码 Head 3:关注调用链关系 Head 4:关注报警标题 Head 5:关注业务关键词 ...

这只是直觉类比,实际 head 的功能是训练中自然形成的。

6. num_key_value_heads = 8:这里使用的是 GQA

配置:

"num_attention_heads": 16, "num_key_value_heads": 8

这说明它不是最朴素的 Multi-Head Attention,而是使用了 GQA:

GQA = Grouped Query Attention

在普通 Multi-Head Attention 中:

Q heads = K heads = V heads

而这里是:

Query heads = 16 Key heads = 8 Value heads = 8

也就是说,每 2 个 Query heads 共享一组 K/V:

16 / 8 = 2

可以理解为:

Q:我想查什么,有 16 个视角 K/V:可被查询的信息,有 8 组,被 Query heads 分组共享

形状大致是:

X: [batch, seq_len, 1024]