文本分类任务Qwen3-0.6B与Bert:实验见解
文本分类任务Qwen3-0.6B与Bert:实验见解
前言
最近在知乎上刷到一个很有意思的提问Qwen3-0.6B这种小模型有什么实际意义和用途。查看了所有回答,有人提到小尺寸模型在边缘设备场景中的优势(低延迟)、也有人提出小模型只是为了开放给其他研究者验证scaling law(Qwen2.5系列丰富的模型尺寸为开源社区验证方法有效性提供了基础)、还有人说4B、7B的Few-Shot效果就已经很好了甚至直接调用更大的LLM也能很好的解决问题。让我比较感兴趣的是有大佬提出小模型在向量搜索、命名实体识别(NER)和文本分类领域中很能打,而另一个被拿来对比的就是Bert模型。在中文文本分类中,若对TextCNN、FastText效果不满意,可能会尝试Bert系列及其变种(RoBerta等)。但以中文语料为主的类Encoder-Only架构模型其实并不多(近期发布的ModernBERT,也是以英文和Code语料为主),中文文本分类还是大量使用bert-base-chinese为基础模型进行微调,而距Bert发布已经过去了6年。Decoder-Only
架构的LLM
能在文本分类中击败参数量更小的Bert吗?所以我准备做一个实验来验证一下。
不想看实验细节的,可以直接看最后的结论和实验局限性部分。
实验设置
-
GPU:RTX 3090(24G)
-
模型配置:
模型 | 参数量 | 训练方式 |
---|---|---|
google-bert/bert-base-cased | 0.1B | 添加线性层,输出维度为分类数 |
Qwen/Qwen3-0.6B | 0.6B | 构造Prompt,SFT |
- 数据集配置:fancyzhx/ag_news,分类数为4,分别为World(0)、Sports(1)、Business(2)、Sci/Tech(3)。训练样本数120000,测试样本数7600,样本数量绝对均衡。数据集展示:
{"text": "New iPad released Just like every other September, this one is no different. Apple is planning to release a bigger, heavier, fatter iPad that...""label": 3
}
- 选择该数据集是在
Paper with code
的Text Classification
类中看到的榜单,并且该数据集元素基本上不超过510个token(以Bert Tokenizer
计算)。因为Bert的最大输入长度是510个token,超过会进行截断,保留前510个token,所以为了进行公平的比较,尽量避免截断。 - 因为是多分类任务,我们以模型在测试集上的F1指标为标准,F1值越高,模型效果越好。
Bert训练细节
Bert
的训练比较简单,将文本使用Tokenizer
转换成input_ids
后,使用Trainer
进行正常训练即可。训练参数(若未单独指出,则代表使用Trainer
默认值):
参数名称 | 值 |
---|---|
lr_scheduler_type(学习率衰减策略) | cosine |
learning_rate(学习率) | 1.0e-5 |
per_device_train_batch_size(训练batch_size) | 64 |
gradient_accumulation_steps(梯度累积) | 1 |
per_device_eval_batch_size(验证batch_size) | 256 |
num_train_epochs(epoch) | 5 |
weight_decay | 1e-6 |
eval_steps(验证频率) | 0.1 |
- 训练过程中模型对测试集的指标变化:
Step | Training Loss | Validation Loss | Accuracy | Precision | Recall | F1 |
---|---|---|---|---|---|---|
938 | 0.191500 | 0.195639 | 0.934737 | 0.935364 | 0.934737 | 0.934773 |
1876 | 0.177600 | 0.179451 | 0.938289 | 0.938485 | 0.938289 | 0.938360 |
2814 | 0.142200 | 0.186385 | 0.936711 | 0.938738 | 0.936711 | 0.936743 |
3752 | 0.146600 | 0.168954 | 0.945526 | 0.945955 | 0.945526 | 0.945572 |
4690 | 0.113500 | 0.176878 | 0.945395 | 0.945408 | 0.945395 | 0.945385 |
5628 | 0.092200 | 0.177268 | 0.945658 | 0.945759 | 0.945658 | 0.945627 |
6566 | 0.081500 | 0.194639 | 0.942763 | 0.943813 | 0.942763 | 0.942817 |
7504 | 0.077600 | 0.191445 | 0.944079 | 0.944362 | 0.944079 | 0.944056 |
8442 | 0.068100 | 0.194431 | 0.944211 | 0.944457 | 0.944211 | 0.944216 |
- 可以看到
Bert
在3752 step(2 epoch)后出现了严重的过拟合,在测试集上最好结果是:0.945
Qwen3训练细节
- 使用
Qwen3
训练文本分类模型有2种方法。第1种是修改模型架构,将模型最后一层替换为输出维度为分类数的线性层。第2种是构造Prompt
,以选择题的方式创建问答对,然后进行SFT
训练。第1种方法相当于仅把模型当做一个embedding
,但这与擅长生成任务的Decoder-Only
训练方式相违背,所以这里不尝试第1种方法,只实验第2种方法。 - 训练框架使用LLama Factory,Prompt模板为:
prompt = """Please read the following news article and determine its category from the options below.Article:
{news_article}Question: What is the most appropriate category for this news article?
A. World
B. Sports
C. Business
D. Science/TechnologyAnswer:/no_think"""answer = "<think>\n\n</think>\n\n{answer_text}"
- 因为
Qwen3
为混合推理模型,所以对非推理问答对要在模板最后加上/no_think
标识符(以避免失去推理能力),并且回答要在前面加上<think>\n\n</think>\n\n
。 - 按照LLama Factory SFT训练数据的格式要求组织数据,如:
{'instruction': "Please read the following news article and determine its category from the options below.\n\nArticle:\nWall St. Bears Claw Back Into the Black (Reuters) Reuters - Short-sellers, Wall Street's dwindling\\band of ultra-cynics, are seeing green again.\n\nQuestion: What is the most appropriate category for this news article?\nA. World\nB. Sports\nC. Business\nD. Science/Technology\n\nAnswer:/no_think",'output': '<think>\n\n</think>\n\nC'
}
- 训练参数配置文件:
### model
model_name_or_path: model/Qwen3-0.6B### method
stage: sft
do_train: true
finetuning_type: full### dataset
dataset: agnews_train
template: qwen3
cutoff_len: 512overwrite_cache: true
preprocessing_num_workers: 8### output
output_dir: Qwen3-0.6B-Agnews
save_strategy: steps
logging_strategy: steps
logging_steps: 0.01
save_steps: 0.2
plot_loss: true
report_to: tensorboard
overwrite_output_dir: true### train
per_device_train_batch_size: 12
gradient_accumulation_steps: 8
learning_rate: 1.2e-5
warmup_ratio: 0.01
num_train_epochs: 1
lr_scheduler_type: cosine
bf16: true
-
因为
Bert
在训练2个epoch
后就出现了严重的过拟合,所以对Qwen3
模型,只训练1个epoch
,每0.2个epoch
保存一个检查点。 -
训练过程中模型对测试集的指标变化(训练结束后加载检查点对测试集进行推理,注意!为保证推理结果稳定,我们选择选项ppl低的作为预测结果):
Step | Training Loss | Accuracy | Precision | Recall | F1 |
---|---|---|---|---|---|
250 | 0.026 | 0.912 | 0.917 | 0.912 | 0.912 |
500 | 0.027 | 0.924 | 0.924 | 0.924 | 0.924 |
750 | 0.022 | 0.937 | 0.937 | 0.937 | 0.937 |
1000 | 0.022 | 0.941 | 0.941 | 0.941 | 0.941 |
1250 | 0.023 | 0.940 | 0.940 | 0.940 | 0.940 |
- 可以看到
Qwen3-0.6B
模型Loss
在一开始就急速下降,然后开始抖动的缓慢下降,如下图(纵轴范围调整0.05~0.015)。在测试集上最好结果是:0.941。
Bert和Qwen3-0.6B RPS测试
- 为测试
Bert
和Qwen3-0.6B
是否满足实时业务场景,对微调后的Bert
和Qwen3-0.6B
进行RPS
测试,GPU
为RTX 3090
(24G):
模型 | 推理引擎 | 最大输出Token数 | RPS |
---|---|---|---|
Bert | HF | - | 60.3 |
Qwen3-0.6B | HF | 8 | 13.2 |
Qwen3-0.6B | VLLM | 8 | 27.1 |
结论
Qwen3-0.6B
在Ag_news
数据集上并未超过Bert
模型,甚至还略逊色于Bert
。Qwen3-0.6B
似乎非常容易过拟合,前期Loss
呈现断崖式下降。Qwen3-0.6B
训练1个epoch
耗时1个3090GPU
时(使用HF推理引擎测试耗时0.5个3090GPU
时),Bert
训练5个epoch
+10次测试集推理共耗时1个3090GPU
时。也就是Qwen3-0.6B训练和推理共耗时1.5 GPU时,Bert训练和推理共耗时1 GPU时。Bert
训练明显快于Qwen3-0.6B
。Bert
的RPS
是Qwen3-0.6B
(VLLM
推理引擎)的3倍。
实验局限性
- 未实验在
Think
模式下Qwen3-0.6B
的效果(使用GRPO
直接训练0.6B
的模型估计是不太行的,可能还是先使用较大的模型蒸馏出Think
数据,然后再进行SFT
。或者先拿出一部分数据做SFT
,然后再进行GRPO
训练(冷启动))。 - 未考虑到长序列文本如
token
数(以Bert Tokenizer
为标准)超过1024
的文本。 - 也许因为
AgNews
分类任务比较简单,其实不管是Bert
还是Qwen3-0.6B
在F1
超过0.94
的情况下,都是可用的状态。Bert
(F1:0.945)和Qwen3-0.6B
(F1:0.941)的差距并不明显。如果大家有更好的开源数据集可以用于测试,也欢迎提出。
okenizer为标准)超过
1024`的文本。 - 也许因为
AgNews
分类任务比较简单,其实不管是Bert
还是Qwen3-0.6B
在F1
超过0.94
的情况下,都是可用的状态。Bert
(F1:0.945)和Qwen3-0.6B
(F1:0.941)的差距并不明显。如果大家有更好的开源数据集可以用于测试,也欢迎提出。 - 未对两模型进行细致的参数调整。
- 未测试两模型在中文文本分类任务中的表现。