资讯动态

微调小模型前先测能力基线:64条SST-2样本实战指南

发布时间:2026/10/6 11:05:47 来源:尧图企业网站定制
很多人拿到一个预训练小模型第一反应就是打开训练脚本开始微调。但你知道吗我见过太多人微调完才发现模型不是不会分类而是不知道你要它输出什么格式或者用训练集的准确率来衡量效果换一套表述就彻底崩盘。这一切的根源就是少了一个微调前的起点测量。我最近在给一个小模型做SST-2情感分类微调动手之前先用手挑的64条开发样本给模型建立了一套能力基线把它现在会什么和它输出的格式是什么样的记得清清楚楚。有了这套基线后面微调配置选择、数据配比调整、过拟合判断全都有了参考系。这篇文章就是把完整的做法、表格模板和踩过的坑整理出来给准备微调小模型的你一个可直接复用的参考。1. 为什么微调前要搞一个能力基线1.1 微调不是凭空捏造能力而是调整已有能力的方向我是从踩坑中才真正理解这个道理的。最初我微调一个小模型做评论情感分析上来就喂了五千条标注数据训了十几个epoch结果模型在训练集上准确率高达95%一到新数据就只会输出那几个训练时反复出现的词。后来我才意识到一个关键事实预训练小模型在预训练阶段就已经学会了大量语言知识微调做的不是从零去教它理解语言而是把它已有的能力往特定任务和特定输出格式上引导。这个理解对基线的意义特别大。既然微调是拨方向那你总得先知道这个方向盘现在指在哪。如果你连模型在当前任务上原本的判断水平都不知道微调后你看到的任何提升都没有参照物。我经常用一个生活类比来解释微调就像培训一个已经会开小轿车的司机去开公交车。这司机懂交规、会踩刹车油门你培训前总得考核一下他现在的驾驶习惯和短板再设计培训方案。如果你连他会不会挂挡都不知道就扔一套教案上去培训效果根本没法评估。能力基线就是这场上岗前考核。1.2 没有基线的三个典型翻车场景没有基线直接微调我总结过三个最常见的翻车场景几乎每个微调项目都能对号入座。第一个是你以为模型很差其实只是格式不对。SST-2是情感二分类任务你期望模型输出positive/negative但预训练小模型在零样本情况下很可能输出一长段解释比如the movie is good because...。你一看答案不对就以为模型能力不行于是拼命加大训练集、增加epoch。但实际上模型只是不知道该按你的格式回答而已一条格式示例或一个prompt模板可能就解决了。没有基线你永远分不清能力不足和格式没对上这两件事。第二个是你以为微调很成功其实测试集样本露馅了。很多人微调完直接在数据集内部切个验证集做评估指标漂漂亮亮换个领域数据立刻拉胯。如果有基线你能看到模型在不同语言现象上的分布表现就不会被一个平均指标蒙住。第三个是无法比较不同微调配置。同样的数据learning rate是2e-5还是5e-5batch size是16还是32哪个更好如果模型在任务上的起点随机性很大你看到的差异可能全是噪声。基线能帮你确定这个改动是真提升还是撞运气。我实际项目里第一类场景遇到最多也最坑人。所以我养成了一个习惯任何微调任务开始前至少花半天做一次基线测量。这半天换来的判断力能帮你省下后面好几天无效训练。2. SST-2 的 64 条开发样本怎么选、怎么用2.1 为什么是 SST-2为什么是 64 条SST-2Stanford Sentiment Treebank 2是情感二分类的经典数据集判断一个句子是正面还是负面。我选它作为基线测试集有这么几个原因句子短、类别清晰、任务直观而且和很多实际业务场景评论分析、客服工单情感判断高度相似。更重要的是SST-2里包含丰富的否定词、转折句、比较结构这些恰恰是小模型最容易翻车的地方。那为什么只抽64条很多人一听测试集就想到几百上千条但这里有个关键区别我们要的不是统计显著性检验而是快速摸清模型的行为模式。64条样本人工一条条看输出只要半小时模型跑一次推理只要几秒钟。这个规模足够让你回答模型大概会不会这个任务的问题。另外64这个数字对内存和显存也很友好每次推理可以一个batch全塞进去不用操心dataloader的边界问题。64的因数多方便分小组对比比如组A放16条简单正例、组B放16条简单负例、组C放16条难例、组D放16条格式测试样本四组各16条刚好四等分。组间差异清晰组内样本量也足够让模型跑出稳定的趋势。2.2 选择样本的三个原则不是随便从SST-2里抽64条就完事的我筛样本主要看三个原则缺一个都会让基线失真。第一个原则是类别均衡。二分类任务positive和negative必须各占一半。有人觉得SST-2句子那么多随机抽就行但实际上随机抽样很容易造成某类偏多模型在正负类上的表现差异就无法公平暴露。基线如果连模型对哪个类倾向性更强都没测出来后面微调数据配比就很难做准。第二个原则是难度分层。只挑简单句子会让基线虚高只挑难句子会误判模型完全不行。我的做法是手动把句子分成三档一眼能判断的比如I loved this movie中等难度的比如有but这类转折词的句子还有带陷阱的比如双重否定、讽刺、反讽句式。每档大约占三分之一。难度分布尽量贴近真实业务数据这样基线才有参考价值。第三个原则是覆盖边界语言现象。SST-2里有大量包含not、never、hardly、without否定词的句子也有as good as这类比较结构。这些边界case最能暴露模型的组合语义能力。比如很多小模型会把It wasnt the worst film判成负面因为它看到worst就条件反射式地触发负向判断。这种样本测的是模型能不能理解否定结构而不只是词表匹配。2.3 怎样组织成开发集选好64条之后组织方式也很重要。我强烈建议用一个csv或jsonl文件保存每条样本至少包含id、text、label、group、test_type这五个字段。group代表分组test_type代表这个样本主要测什么。我实际用的文件长这样id,text,label,group,test_type 001,a moving and beautiful film,positive,easy_pos,positive_vocab 002,the movie is a waste of time,negative,easy_neg,negative_vocab 003,it was not as bad as i expected,positive,negation,double_negation 004,a film that fans of the genre will enjoy,positive,hard_pos,genre_fan ...这样组织最大的好处是当你看到模型在某个样本上犯错可以快速定位到它是哪个环节出了问题。比如如果negation组全错那问题就是否定词处理能力缺失如果hard_pos组全对但easy_neg错了一堆那可能是负向词表覆盖不全。基线不应该只是给模型打个分更应该是定位问题位置的诊断工具。3. 实操过程给小模型建立基线3.1 选取小模型进入具体操作前先定模型。我建议不要一上来就用BERT-large这种大参数模型而是从参数量100M以下的模型开始。原因很简单微调是个快速迭代的过程基线阶段最重要的是跑通流程、验证思路选轻量模型能节省大量时间。后面要换更重的模型流程和指标都一样直接替换backbone就行。我实际用过且推荐的几个小模型给大家列个表模型参数量适合场景BERT-tiny4.4M极快速验证、内存受限设备DistilBERT-base66M均衡性能和速度的默认选择ALBERT-base12M显存紧张但需要一定表达能力MiniLM-L622M多语言任务、embedding复用强调一下基线测试用哪个模型都行关键是要记录下模型名、版本、分词器的cased/uncased配置。SST-2的句子大多是小写英文uncased模型就够用了。但如果你的业务数据里有大小写敏感信息就必须选cased模型。这个选择会影响基线可别忽略。3.2 用 64 条样本测零样本能力现在说最核心的一步怎么测。所谓零样本能力就是直接把句子丢给模型不提供任何任务示例看它怎么回答。但这里有个很多人没注意到的陷阱如果用AutoModelForSequenceClassification来加载预训练模型它加的classification head是随机初始化的跑出来的结果根本不能反映模型的语言理解能力只是随机噪声。那怎么测真实的零样本能力呢我推荐两个方案。方案一使用带任务头的fine-tuned模型。HuggingFace上很多模型本身就带SST-2微调过的分类头比如一些distilbert模型就有sst-2版本。直接用这种模型做baseline能给你一个能力上限参考但它已经不是真正的微调前状态了。方案二用生成式小模型配合prompt模板。这是我最常用的方式。拿GPT-2 small这类模型设计一个promptSentiment of the sentence ... is然后看生成的是positive还是negative。这种方式最接近真实业务里模型的使用方式测的也是模型最核心的语言知识。这里贴一段我跑测的代码用的是transformers库from transformers import AutoTokenizer, AutoModelForCausalLM import torch model_name gpt2 tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained(model_name) model.eval() prompt_prefix Sentiment of the sentence \{}\ is def predict(text): prompt prompt_prefix.format(text) inputs tokenizer(prompt, return_tensorspt, truncationTrue, max_length128) with torch.no_grad(): outputs model.generate( **inputs, max_new_tokens8, do_sampleFalse ) generated tokenizer.decode(outputs[0][inputs[input_ids].shape[1]:], skip_special_tokensTrue) return generated.strip()跑了之后你会发现模型可能输出positive也可能输出positive feelings还可能输出一个完整的句子。这些输出风格差异本身就是重要的格式信息后面要单独记录和解析。3.3 记录输出格式与能力指标跑完64条样本不要只记对错还要记录输出格式和解析情况。我通常用一个四列的表来做记录样本ID期望标签实际输出输出合规001positivepositive是002negativenegative是003positivenot bad, so positive否............合规性的定义要看你的下游需求。如果微调目标是让模型输出JSON那合规就代表输出是合法JSON且包含预期字段如果只是二分类标签那合规就代表输出能被解析成positive/negative。能力指标方面我会同时计算三个数准确率64条里正确分类的比例格式合规率64条里输出能被正常解析的比例有效准确率在格式合规的样本里正确分类的比例为什么有效准确率这么重要我举个例子。假设模型输出了40条positive、20条negative、4条乱码。表面准确率不高但如果把那4条乱码去掉剩下的60条里模型其实分对了58条。这说明模型能力其实不差只是少数输出格式出了偏差。有效准确率能帮你区分能力短板和格式短板这两个问题的解决方式完全不同。3.4 建立评判标准有了原始记录接下来就是汇总成一份简洁的基线报告。我习惯用一张表来呈现指标数值说明总样本数64准确率52%33/64略高于随机格式合规率88%56/648条输出不符合要求格式有效准确率59%33/56在合规输出中表现强于随机主要失分类型否定词、双重否定模型看到否定词就判负这份报告是微调决策的依据。比如格式合规率只有50%那微调的第一优先级就是让模型学会输出标准格式训练方式可以靠few-shot示例或约束解码来解决。如果格式合规率有90%但准确率低那微调的重点就应该是语义理解数据配比要向难题倾斜。同一个64条样本可以给出完全不同的指导方向。4. 常见问题与排查技巧4.1 样本筛选中的坑筛选64条样本这件事看着简单实际操作中坑比想象的多。我踩过不少挑几个典型的说。第一个坑是只选自己有把握的句子。人工筛样本时你会下意识地挑一眼能判断正负的句子结果64条全偏简单了。我的解决办法是强迫自己按简单/中等/难三档来筛每档至少16条难句绝不低于四分之一。第二个坑是忽略长度分布。SST-2里有大量短句5个词以内也有不少长句。如果64条全是短句模型在长句上的表现就完全测不到。我一般要求至少留15条超过15个词的句子这样能暴露模型的长程依赖问题。第三个坑是重复结构。有些句子虽然用词不同但结构几乎一样。比如a delightful movie、a charming film、a lovely story模型只要学会这些形容词是好评就能全过测不出真正的句法理解。筛样本时要刻意去重保留结构多样的句子。4.2 格式评估的具体做法格式评估不是简单地看看输出里有没有positive这个子串这里面的细节规则很多我总结了几条硬规则。第一条标签词必须是独立词。positive出现在not positive里不能算正面的合规输出因为含义完全反了。所以要检查单词边界而不是做简单的子串匹配。第二条输出不能自相矛盾。有些模型会输出positive and negative或者both good and bad这种输出即使包含了关键词也不能算合规。第三条要容忍大小写和标点差异。如果微调目标里要求严格JSON那Positive和positive严格来说算不合规但如果只是关心语义分类解析时应该统一用lower()来归一化。这个标准必须在基线报告里写明不然微调后你根本不知道模型是变好了还是变差了。我实际写了一个简单的格式校验器逻辑大致是这样def format_checker(text): t text.strip().lower() if t in (positive, negative): return strict_pass if positive in t and negative in t: return conflict if positive in t or negative in t: return fuzzy_fail return no_label这个校验器把模型输出分成了四档。观察模型在这四档上的分布变化比单纯看准确率更能反映微调过程中发生的事情。有些模型从no_label进步到fuzzy_fail其实已经是很大进步虽然准确率还没体现出来。4.3 基线表格模板这边分享一个我长期在用的基线记录模板你复制过去改改字段就能用。首先是汇总部分# 基线报告 ## 模型信息 - 模型名gpt2 - 微调方式无 - 测试日期202X-XX-XX ## 汇总指标 | 指标 | 数值 | |------|------| | 准确率 | xx% | | 格式合规率 | xx% | | 有效准确率 | xx% | | 主要失败模式 | 否定词处理、格式不完整 | ## 分组表现 | 分组 | 样本数 | 准确率 | 主要问题 | |------|--------|--------|----------| | easy_pos | 16 | 90% | 无 | | easy_neg | 16 | 80% | 个别负向词不识别 | | hard_pos | 16 | 50% | 转折句理解差 | | negation | 16 | 25% | 双重否定几乎全错 |这个模板最大的价值是它能把现象沉淀下来。微调完以后你拿同一套64条样本再跑一遍两张表一对比立刻能说出这次微调到底带来了什么改变。如果不同组的提升幅度不一样你还能继续深挖是哪类语言现象没有覆盖到。还有个小建议组名不要只写easy/hard把语言现象也写进去。比如negation、contrast、comparative这些命名方式能让记录表变成一份诊断报告而不是简单的分数汇总。5. 基线与微调目标的联动5.1 用基线决定微调数据基线不是做完就完事的它最大的价值是指导微调数据的配比。我举个例子假设基线报告显示negation分组的准确率只有25%那微调训练集里就要多放一些带not、never、hardly、without这些词的样本。如果easy_pos已经90%了那训练集里就没必要堆太多简单句把多出来的额度留给难点。具体操作时我会在微调数据集构建阶段根据基线短板做标注比例调整。假设原来1000条数据正负各500看完基线后把negation相关样本提升到总样本的15%到20%。注意不能太过头否则微调后模型在正常句子上反而会变差。微调后我会在同一套64条样本上复测如果negation提升了20%但easy_pos从90%掉到70%那就是典型的灾难性遗忘或数据配比失衡需要马上调整。5.2 用基线防止过拟合和格式崩塌微调小模型最常见的两个毛病一个过拟合一个格式崩塌。基线的价值在于它们都能被提前发现。过拟合怎么通过基线发现训练过程中每跑完一个epoch就拿到那64条样本上测一次。你会发现准确率大概率先升后降或者在某个点之后训练集准确率还在涨但基线准确率开始掉。这个拐点就是early stopping的最佳时机。没有基线的模型你只能靠人肉观察验证集loss效果差很多。格式崩塌这个更有意思。有些模型微调后能力指标上去了但输出格式反而变差了。比如原本还会输出完整句子微调后变成只输出一个词甚至输出[PAD]。这在生成式小模型微调里特别常见。有了基线报告里的格式合规率你就能一眼看出这轮微调是不是把格式搞坏了。我之前有一版微调准确率从52%升到78%但格式合规率从88%降到60%一看就知道训练目标设置有问题。解决办法也很直接降低学习率、增加格式示例的权重或者在训练目标里加辅助loss。但前提是你先通过基线发现了这个问题否则训练出来之后看着什么都对就是上线才崩。5.3 基线的扩展RAG小模型场景聊到这里顺带回应一个最近很热的问题小模型能不能做个人知识库RAG。这个问题本身和基线的思路是相通的。你可以在微调前先用少量样本测试模型对结构化知识的阅读理解能力给它一段文字看它能不能从中抽取出关键信息。如果基线得分很低那说明小模型直接从文本里提取知识的能力有限你更应该考虑RAG加prompt的方案而不是靠微调硬啃。如果基线还不错就可以用微调来强化输出格式的稳定性比如强制输出JSON结构。这里的决策路径和SST-2基线完全一样先搞清楚模型手里有什么再决定要教它什么。所以微调前先测什么这个原则放之各种NLP任务而皆准。6. 实操总结与经验提醒最后分享几个我在实际搭建基线过程中反复验证过的经验希望能帮你少走弯路。第一条基线测试不要只跑一次。模型的零样本输出对prompt措辞非常敏感你换一个提示词结果可能就差很多。我的做法是把64条样本用两三种prompt模板各跑一遍取一个平均结果这样得到的基线更稳定不会因为某次生成的随机性导致判断错误。第二条64条样本虽然小但它是活的。微调以后你还要反复用这64条样本来复测。为了复测有意义这64条样本必须是完全冻结的不能因为微调效果不好就随意换样本或者改标签。这个纪律非常重要否则基线就变成移动靶永远没有参考价值。第三条把64条的原始输出完整保存下来不要只保存预测标签。我经常在微调前后回看模型的原始输出发现一些数值指标没体现出来的变化。比如模型在微调前输出this is a great movie, i liked it a lot微调后变成positive。这当然是进步但如果你只保存预测标签就会丢失模型学会了输出压缩表达这个重要信息。第四条如果你的业务任务不是SST-2而是别的场景这个64条样本基线法完全可以直接平移。核心步骤不变标签均衡、难度分层、覆盖边界现象、记录格式和能力两套指标。只要把这四点做好无论哪个小模型微调项目都能快速得到可靠的起点。我自己的习惯是每次微调项目启动前把基线报告打印出来贴在工位旁。训练过程中每次看实验结果先对照基线找差异再决定下一步动作。这套流程看起来朴素但真的帮我避免了很多盲目调参的无效工作。如果你正准备微调自己的小模型不妨先从64条开发样本开始测一测模型到底站在哪里。测完你会发现微调前的这几十分钟是整个项目里性价比最高的投入。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑