微调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 = 3072 | MLP 中间层升维到 3072 |
hidden_act = silu | MLP 使用 SiLU 激活函数 |
vocab_size = 151669 | tokenizer 词表大小 |
max_position_embeddings = 40960 | 最大上下文长度约 40960 token |
rms_norm_eps = 1e-6 | RMSNorm 的数值稳定参数 |
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]