迁移学习实战:用Transformers库微调预训练模型的完整指南
发布时间:2026/9/10 18:35:47来源:尧图网络
迁移学习这四个字在我刚开始接触深度学习时还是个偏学术的概念现在却几乎成了每个做 NLP 项目的人的日常。而 Hugging Face 的 Transformers 库更是把预训练模型的加载、微调、部署全部封装成了顺手得不能再顺手的 API。但越是这样越容易让人忽略实操里的关键细节——版本怎么配、数据怎么洗、参数怎么调、显存不够怎么办。这篇文章我就围绕「迁移学习怎么落地」这个主题把用 Transformers 库做微调的完整流程和经验写一遍适合刚入门 NLP 微调的朋友也适合已经跑过一些代码但总感觉不稳的开发者。内容不算难但每一步都有讲究照着走一遍你会比直接复制教程代码多明白不少底层逻辑。1. 先想明白迁移学习到底在解决什么问题1.1 迁移学习和微调究竟什么关系很多人刚接触时会疑惑迁移学习和微调是不是同一个东西答案是有重叠但不是一回事。迁移学习是一种学习范式指的是把模型在源任务上学习到的知识迁移到目标任务上用来降低目标任务对数据量和训练成本的要求。而微调则是迁移学习最主流的一种实现手段在预训练权重的基础上用目标任务的数据继续训练让模型参数逐步适配新任务。我习惯用一个比方解释给新人听预训练模型相当于一个读过大量通识书籍的毕业生他懂语言结构、懂世界常识、懂上下文语义但他还没学过“情感分析”这门专业课。微调就是给他上几节针对性的专业课让他把已有的通识能力转化为解决具体问题的能力。这也就是为什么预训练模型的底子越厚微调之后的天花板越高——你不可能指望一个语文很差的模型靠微调突然变得逻辑严密。从技术实现角度说微调的本质是让预训练模型在新任务的数据分布上继续做梯度下降。关键点在于预训练阶段已经让模型学习到了非常好的参数初始化位置新任务只需要在这个位置上做小幅修正。这也解释了为什么微调通常只需要很小的学习率——你是在精修不是在重造。1.2 什么场景适合用迁移学习什么场景不适合搞清楚“什么时候该用迁移学习”比“怎么用”更重要。我见过太多人明明数据量足够、任务分布和预训练语料差别很大却硬要套迁移学习的方案最后效果还不如自己从零训练的小模型。适合用迁移学习的场景有这么几类第一目标任务标注数据很少。比如只有几千条甚至几百条标注样本从零训练一个深层模型几乎不可能收敛但用预训练模型微调哪怕数据少也能学出不错的效果。第二通用语义理解占主导的任务。文本分类、命名实体识别、情感分析、文本相似度这些任务底层能力高度依赖通用语言理解预训练模型的能力可以直接迁移。第三你的算力资源有限。预训练动辄几十万张显卡小时但微调消费级显卡也能跑这也是迁移学习最现实的优势。不太适合的场景也有目标任务和预训练语料分布差异极大比如预训练语料全是通用网络文本你的任务是分子式解析或特殊符号密集的代码片段——这类任务要么重新预训练一个领域模型要么先用领域语料做增量预训练再走微调流程。另外如果你手里有百万级标注数据且任务非常特殊从零训练一个适中规模的模型往往效果和微调差不多这时候迁移学习的优势就没那么明显了。还有一点需要提醒迁移学习不是“模型越大越好”。模型越大微调所需的显存和数据量都水涨船高。后面我会专门讲大模型时代的 LoRA 微调但即便有 LoRA也不是所有任务都需要百亿参数模型来压场子。2. 动手前的关键准备版本、硬件、模型选择2.1 Transformers 库与 PyTorch、CUDA 的版本配套关系我估计不少人是被热搜词里“哪个版本的 pytorch 和 cuda 支持 transformers3.4.0”这种问题勾进来的。这个提问非常典型八成是照着某个老教程安装结果版本对不上直接报错。关于 transformers3.4.0我直说结论这是 2020 年底的版本对应 PyTorch 1.6 到 1.7 时代CUDA 10.1、10.2、11.0 都基本兼容。如果你不是有必须复现的老代码我不建议新项目再碰这个版本因为那个时期的 API 设计和现在差别比较大很多新特性、新模型都不支持排查问题也不方便。新项目我的建议是直接上 Transformers 4.x 的最新稳定版配 PyTorch 2.xCUDA 11.8 或 12.1 都行。为什么这么配因为 Transformers 4.x 的 Trainer API 已经非常成熟原生支持混合精度、梯度累积、断点续训而且模型库覆盖了几乎所有主流预训练模型。安装的时候注意一个容易踩的雷不要用 pip 直接装 transformers 然后不管依赖最好先装好 PyTorch再装 transformers。因为 Hugging Face 的依赖检测不会自动帮你挑选和 CUDA 版本匹配的 PyTorch如果先装 transformerspip 可能会顺手拉一个不兼容的 torch 版本进去。2.2 怎么选一个合适的预训练模型选模型是微调成功的一半。原则很简单尽量选和你的目标任务、语言、数据分布接近的模型而不是盲目追求模型排名。中文任务的话老牌选择是 bert-base-chinese优点是中文语料训练充分、社区资料多、出了问题容易搜到答案。如果你做的是新闻分类、电商评论这类比较日常的文本chinese-roberta-wwm-ext 通常效果比 bert-base-chinese 好一点因为它用了全词掩码策略对中文词的边界感知更强。如果任务偏严肃比如法律、医疗、金融领域建议优先考虑领域预训练模型比如在法律语料上继续预训练过的 Lawformer 系列或者你在通用模型基础上自己用领域语料做增量预训练——这一步叫 Domain-Adaptive Pretraining实践里经常能拉开一两个点的差距。英文任务的选择就更多了。分类和序列标注类任务RoBERTa 系列一直很稳需要处理长文本的Longformer 和 BigBird 值得考虑但它们的注意力机制占用显存更大小显存显卡慎用。如果对推理速度有要求DistilBERT 这类蒸馏模型是很好的折中方案效果只比原版差几个点速度却快一倍不止。还有个实用技巧去 Hugging Face Model Hub 搜任务关键词比如搜索“chinese sentiment”能找到大量社区用户上传的已经微调好的模型。先用这些模型做推理测试如果效果已经满足需求那就不用自己微调了。如果效果不达标选一个表现最好的作为起点继续微调也能省不少时间。这个思路很多人想不到我每次做新任务都会先搜一圈 Model Hub至少能省几小时。2.3 数据准备格式、清洗和分布检查数据处理这块我每次带新人都会强调模型是死的数据是活的数据质量直接决定微调上限。很多人的模型效果不好问题根本不在参数设置而是数据本身。首先是数据格式。用 Transformers 库做监督微调最常用的格式是 CSV 或 JSON 文件每行一个样本包含文本字段和标签字段。分类任务的标签建议直接用整数比如 0、1、2不要用字符串减少没必要的转换。序列标注任务则需要把每个 token 的标签对齐好这个对齐环节稍后我会单独讲因为它非常容易出错。其次是数据清洗。别看这一步不起眼脏数据对微调效果的杀伤力极大。我处理过一个电商评论分类项目准确率一直卡在 84% 上不去后来把数据拉出来逐条看发现不少文本夹杂着 HTML 标签、表情符号和重复的促销语清洗之后准确率直接到了 90%。清洗的常规动作包括去 HTML 标签、去乱码、统一英文大小写、去除文本开头结尾的空白符号。还有一点数字要不要归一化需根据任务决定如果是商品价格相关的分类直接保留原始数字反而更合理。最后是分布检查。微调之前用train_test_split划分训练集和验证集后最好统计一下标签分布确认训练集和验证集的标签比例不要差太多。我自己遇到过验证集恰好全是一个类别的情况导致评估指标看起来非常离谱。如果标注数据的来源差异较大比如一部分来自评论平台A、一部分来自平台B建议随机划分数据时要按来源分层抽样避免模型只学到了平台A的风格。3. 微调全流程实操从数据加载到模型训练3.1 用 Dataset 和 Tokenizer 把数据变成模型能吃的形状万事俱备之后来跑一个最经典的文本分类微调流程。目标任务是微博情感二分类数据是 CSV 文件两列text 和 label。第一步是加载数据。Transformers 库虽然自带一些load_dataset可以直接加载 Hugging Face 数据集仓库里的数据但更常见的情况是加载本地数据。在 Transformers 4.x 里datasets库提供了load_dataset(csv, data_filesmy_data.csv)这样的方式它会自动把数据封装成 Dataset 对象支持按批次读写效率远高于直接用 pandas 读完再转。第二步是加载预训练模型和 Tokenizer。我这里以bert-base-chinese为例from transformers import AutoTokenizer, AutoModelForSequenceClassification model_name bert-base-chinese tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForSequenceClassification.from_pretrained( model_name, num_labels2 )这里有个细节值得注意num_labels必须和你的类别数一致。如果你的任务是二分类就是 2如果标签是 0 到 4 的五分类就是 5。模型加载时Hugging Face 会保留预训练权重同时会替换掉最后一层分类头随机初始化一个适合你类别数的新分类头。所以如果你发现加载模型之后模型的参数数量和预训练时不完全一样很正常。第三步是 tokenize。我强烈建议用tokenizer对整批数据做批量处理而不是一条一条处理因为批处理可以自动做 padding 和截断效率高很多。一个标准的处理函数长这样def preprocess_function(examples): return tokenizer( examples[text], truncationTrue, paddingmax_length, max_length128, )max_length的选择很有讲究。BERT 类模型最长支持 512 个 token但并不是所有任务都需要这么长。我一般先统计一下数据的 token 长度分布如果 95% 的样本都在 100 个 token 以内那设置max_length128就够了。设得太长会让 padding 大量增加浪费显存设得太短又会截断关键信息。这个参数值得花几分钟统计分析。3.2 用 Trainer API 微调核心配置逐一拆解Transformers 库提供了两种微调方式手写训练循环或者用自带的 Trainer。我的建议很简单除非你有非常特殊的训练逻辑比如多任务学习、自定义损失函数否则直接用 Trainer省心且不容易出错。Trainer 用起来需要准备一个TrainingArguments对象这里面的参数非常多我挑几个最关键的细说。from transformers import TrainingArguments, Trainer training_args TrainingArguments( output_dir./results, eval_strategyepoch, save_strategyepoch, learning_rate2e-5, per_device_train_batch_size16, per_device_eval_batch_size64, num_train_epochs3, weight_decay0.01, warmup_ratio0.1, logging_steps50, load_best_model_at_endTrue, metric_for_best_modeleval_accuracy, fp16True, )learning_rate是第一个要重点说的参数。微调预训练模型时学习率通常设置在1e-5到5e-5之间这个区间比从头训练模型时的学习率小一两个数量级原因前面提过微调是精修不是重建。如果设得太大模型会很快忘掉预训练学到的知识出现灾难性遗忘。我见过太多人直接套用从头训练时的1e-3学习率结果 loss 直接起飞。per_device_train_batch_size要结合显存来定。以 16GB 显存为例BERT-base 模型 128 长度下batch size 设为 16 通常没问题。显存不够时优先用梯度累积来弥补而不是硬撑大 batch size。fp16这个参数建议直接开。现代 GPU 对半精度训练支持得很好几乎不损失精度的情况下显存占用能省一半训练速度也能提上来不少。如果你的显卡是 V100、T4、A100、RTX 20 系及以上都支持老一点的 GTX 10 系列不支持快速 fp16 训练开了反而可能更慢。warmup_ratio表示训练前多少比例的训练步骤采用线性学习率预热。这个机制的用意是训练刚开始时模型权重还比较接近预训练状态步子不宜迈得太大先用小学习率热身让优化器状态稳定下来再切到正式的学习率。一般设 0.05 到 0.1 之间比较合适。然后是 Trainer 自身的参数。除了刚才的model、args、train_dataset、eval_dataset还需要一个compute_metrics函数来计算你关心的评估指标。分类任务最常用的是准确率from evaluate import load import numpy as np accuracy_metric load(accuracy) def compute_metrics(eval_pred): logits, labels eval_pred predictions np.argmax(logits, axis-1) return accuracy_metric.compute( predictionspredictions, referenceslabels )注意eval_pred返回的是原始 logits 而不是概率所以一定要用np.argmax取预测类别。忘了这一步的话你可能会看到准确率惨不忍睹。最后运行一句trainer.train()训练就开始了。如果你设置了load_best_model_at_endTrue和metric_for_best_model训练结束后trainer.model会自动加载验证集上指标最优的权重不用手动挑。3.3 训练完成后的保存、加载与推理训练完成之后很多人直接就torch.save(model.state_dict())存权重这种做法不是不行但有个隐患你存的只是权重没有存配置文件、tokenizer 和训练参数。下次加载时还得手动构造模型结构配置稍有对不上就报错。更稳妥的做法是用 Transformers 库原生的save_pretrainedmodel.save_pretrained(./my_sentiment_model) tokenizer.save_pretrained(./my_sentiment_model)它会把模型权重、配置文件、tokenizer 文件都保存在同一个目录下。推理时只需要一行代码就能加载回来from transformers import AutoModelForSequenceClassification, AutoTokenizer model AutoModelForSequenceClassification.from_pretrained(./my_sentiment_model) tokenizer AutoTokenizer.from_pretrained(./my_sentiment_model)推理时的 tokenize 要注意单条样本不需要padding但需要用return_tensorspt指定返回 PyTorch 张量否则你拿到的是 Python 列表没法直接送进模型。inputs tokenizer(这个产品真的太好用了, return_tensorspt) outputs model(**inputs) probs torch.softmax(outputs.logits, dim-1).squeeze()如果这个模型后面要部署到线上建议再用torch.compile()或者 ONNX Runtime 做一步加速尤其是并发请求量上来之后纯 PyTorch 推理的吞吐量往往不够看。这一步离微调本身稍远但属于落地必须考虑的事。4. 微调过程中的常见问题与排查技巧实录4.1 显存溢出OOM 了先别急着重启显存溢出是微调最常见的问题几乎每个人都会遇到。我最早跑 BERT-large 微调时4 张显卡的配置都能 OOM当时还不太懂优化就傻傻地调小 batch size调到 4 才不炸但训练速度慢得让人崩溃。后来我总结了一套 OOM 排查顺序第一先看是不是真的显存满了。用nvidia-smi看 GPU 显存占用如果其他进程也占着显存先清掉。很多人本地开了一堆测试程序忘了关白白占掉十几个 G。第二如果确认是模型本身占用过大最优先的手段是开梯度累积。假设你想用 batch size 32 的效果但显存只够 8那就用per_device_train_batch_size8同时gradient_accumulation_steps4这样实际每个优化步骤的等效 batch 是 8×432。梯度累积的原理是把多个小批次的梯度累加后再更新权重效果上接近大批次训练。这是我在显存不够时最常用的招数。第三开启梯度检查点gradient checkpointing。Transformer 模型的激活值在反向传播时占用大量显存梯度检查点以少量计算换显存节省开启方式一行代码model.gradient_checkpointing_enable()开启后显存占用能降低约 30% 到 50%代价是训练速度会慢一些。建议在 batch size 实在降不下去、梯度累积也救不了的时候再用。第四确认是否真的需要那么大的max_length。很多文本实际长度并不长但你把 max_length 设成了 512结果大量 padding token 白白占着显存。我统计过一个真实的电商评论数据集平均文本 token 长度只有 40设成 512 纯属浪费。这个排查点患者在训练前就该做但我经常看到人等到 OOM 才发现。4.2 训练 loss 不降或者振荡学习率是第一嫌疑loss 不降是最让人挫败的情况。我见过有人为此怀疑模型有问题、数据有问题甚至怀疑人生但大部分时候问题都出在学习率上。训练刚开始时 loss 不降是正常的尤其是学习率还有 warmup 阶段时前几百步模型基本是在热身。如果过了三分之一训练轮次 loss 还在原地踏步就要检查学习率是不是太小了。可以尝试把学习率从2e-5调到5e-5再看看。反过来如果 loss 一开始降得很快但随后剧烈振荡不收敛那多半是学习率太大模型在最优解附近来回震荡。这时候可以把学习率除以 10或者增大 warmup 比例。还有一种被我称为“假性不收敛”的情况loss 一直在降但验证集指标纹丝不动。这种通常是验证集数据分布和训练集有较大偏差或者验证集样本太少、噪声太大。先检查验证集标签分布再确认划分数据的随机种子是否固定。我做过一个项目验证集指标忽高忽低最后发现是验证集只有 200 条样本随便换一批数据波动就很明显。后来把验证集扩大到 2000 条指标才稳定下来。4.3 过拟合怎么判断、怎么解决微调预训练模型数据量少的时候很容易过拟合。判断标准很直观训练 loss 持续下降验证 loss 先降后升或者验证集准确率上到某个点开始下滑。过拟合的本质是模型把训练集里特有的模式当成了一般规律比如训练集中所有“好评”都出现了“物流快”三个字模型就学会了看到“物流快”就预测好评一旦验证集里出现“物流快”却是中评的样本预测就错了。解决过拟合我一般按优先级试这么几招第一早停。Trainer本身不直接内置 early stopping但配合EarlyStoppingCallback很容易实现。监听验证 loss连续 N 个评估周期不下降就提前停止训练。这是成本最低、效果最明显的手段。第二调低学习率、增加weight_decay。weight_decay是权重衰减本质是给模型参数加一个 L2 正则约束让权重不要学得太极端。分类任务里默认 0.01 起步过拟合严重时可以调到 0.05。第三做数据增强。文本分类任务可以用 EDA同义词替换、随机插入、随机交换、随机删除这种简单的增强方式也可以用回译——把中文翻译成英文再翻译回中文生成语义不变但表达不同的新样本。第四如果以上都试了还是不行可以尝试冻结预训练模型靠前的若干层只微调靠近输出的几层。这样做的好处是减少可训练参数量限制模型过强的拟合能力。实现方法也不复杂遍历模型的参数把靠前层的requires_grad设为 False 即可。4.4 常见问题排查速查表症状根因处理方式OOM 显存溢出batch size 过大 / 序列过长 / 其他进程占显存梯度累积 → 梯度检查点 → 降低 max_length → 清空其他进程训练 loss 不降学习率过小或过大先确认 warmup 阶段再调学习率到 1e-5~5e-5验证 loss 反弹上升过拟合早停、增大 weight_decay、数据增强、冻结底层训练很快但指标差学习率太大导致灾难性遗忘学习率降到 5e-6 左右重训验证集指标剧烈波动验证集样本太少或分布不均扩大验证集、分层采样、固定随机种子一批数据跑完 loss 变成 NaN学习率过大 / 数据中有脏值调低学习率、检查文本是否有 NaN 或异常字符加载模型时维度不匹配num_labels 设置和前一次不同删除旧的 checkpoint重新定义 num_labels这张表是我这几年踩坑的浓缩版。遇到问题先看表能少走很多弯路。5. 进阶方向从全参微调到 LoRA 与大模型微调5.1 为什么 LoRA 会成为微调主流BERT 时代的微调还算温和因为模型参数少则 1 亿多的也就 3 亿多消费级显卡全参微调问题不大。但到了大模型时代动辄几十亿上百亿参数全参微调对于绝大多数团队来说既不现实也没必要。LoRA 就是在这样的背景下火的。LoRA 的核心思路很巧妙微调时冻结预训练模型原有参数在每一层注意力模块的权重旁边额外加入两个低秩矩阵的乘积只训练这两张小矩阵。假设某个原始权重矩阵是 4096×4096LoRA 的秩设为 16那要新增训练的参数量就是 4096×16 16×4096约 13 万个参数只占原来的 0.8% 左右。训练完成后把 LoRA 权重和原始权重合并或者单独保存一份小的 LoRA 适配器文件。实际使用里 LoRA 带来的好处非常明显。第一显存占用大幅降低一张 24GB 的消费级显卡就能微调 7B 甚至 13B 的模型。第二训练速度快因为大部分参数冻结反向传播时只需要计算和更新少数矩阵的梯度。第三扩展性好同一个底模可以挂载多套 LoRA 适配器换任务只需要换适配器不需要重新部署整个模型。不过 LoRA 也不是没有缺点。秩的选择直接影响微调能力秩太小可能拟合不足秩太大又会失去低秩约束的意义。实践中我一般从 8 开始试效果不够再往上加到 16 或 32。另外LoRA 主要作用于注意力层的权重矩阵对某些需要大规模改变行为模式的任务可能不如全参微调来得彻底。所以如果任务本身比较简单LoRA 完全够用但任务复杂度很高还是要评估全参微调或者部分层微调。5.2 用 PEFT 库做 LoRA 微调的实操要点Hugging Face 官方维护的 PEFT 库把 LoRA 封装得足够简单。一段最小的 LoRA 微调代码如下from peft import LoraConfig, get_peft_model lora_config LoraConfig( r8, lora_alpha32, target_modules[q_proj, v_proj], lora_dropout0.1, biasnone, ) lora_model get_peft_model(model, lora_config) print(f可训练参数占比: {sum(p.numel() for p in lora_model.parameters() if p.requires_grad) / sum(p.numel() for p in lora_model.parameters()):.4%})几个参数逐个说。r是低秩矩阵的秩决定新增参数量lora_alpha是 LoRA 矩阵的缩放系数实际生效的缩放比例是lora_alpha / r所以调大 alpha 等价于增大 LoRA 的更新幅度target_modules指定要注入 LoRA 的网络层模型不同层的命名也不一样可以先打印model.named_modules()看准确的模块名lora_dropout是 LoRA 层的 dropout 比例微调数据量越少dropout 可以适当设高一点防过拟合。我自己的经验是q_proj和v_proj这组搭配是大多数任务的稳妥起手式。如果效果不够再把k_proj和o_proj也加进来可训练参数会多一些拟合能力更强但过拟合风险也随之上升。训练过程和普通微调几乎一样还是可以继续用 Trainer只是传入的 model 要换成get_peft_model包装过的。训练结束后LoRA 权重可以用lora_model.save_pretrained()单独保存保存出来的文件通常只有几十兆分发和部署都很方便。推理时先加载底模再加载 LoRA 权重from peft import PeftModel base_model AutoModelForCausalLM.from_pretrained(your_base_model) lora_model PeftModel.from_pretrained(base_model, ./my_lora_adapter)如果你要的是“微调完直接合并回底模”的效果PEFT 也提供了lora_model.merge_and_unload()方法合并后可以直接像普通模型一样保存和部署。我之前做私有化部署时就喜欢用合并模式因为部署端不需要安装 PEFT 库少一层依赖就少一个出错点。5.3 大模型微调工具链从原生训练到 LLaMA-Factory聊到大模型微调就绕不开工具链这个话题。现在市面上的选择很多但我的建议是先搞清楚自己到底需要什么再选工具不要为了追新而追新。如果你本身对 Transformers 库和 Trainer 已经很熟且目标模型在 Hugging Face 上有分布用 PEFT Transformers 组合就够了灵活性最高。像 Qwen、Llama、DeepSeek 这些主流开源模型的底座都能在 Hugging Face 或者 ModelScope 上找到走的路子和我前面讲的文本分类微调完全一致只是把任务类型从AutoModelForSequenceClassification换成了AutoModelForCausalLM。如果你需要的是一条更省心的路径LLaMA-Factory 是目前社区里口碑很好的大模型微调工具。它把 LoRA、QLoRA、全参微调、DPO、RLHF 等一大堆训练方案都封装成了配置文件驱动的方式用起来基本不需要写训练代码。我个人推荐它的理由是数据管理做得不错支持 ChatML、ShareGPT 等多种指令数据格式不用自己手写解析。对于完全没有训练经验只是想快速验证某个基础模型在自己的业务数据上效果如何的人我反而建议先用各家云平台上的微调服务跑通一次再回来自建。后者涉及资源调度、训练监控、模型评测、部署上线链路比单纯的训练长得多先验证效果再做工程投入是比较务实的顺序。还有一件事如果你的目标只是在教学演示中用一个小模型展示微调前后的效果差异除了deepseek-r1:1.5b之外qwen2.5-3b-instruct和llama3.2-3b都是很合适的选项效果对比明显训练资源要求也不高。这种场景下重点不是追求极致效果而是让模型在微调前答得乱七八糟、微调后能规范回答LoRA 用上以后整个流程十几分钟就能跑完学生看完会非常直观地理解“微调到底改变了什么”。6. 写在最后的一点实在话文章写到这儿主线流程已经全部过了一遍。从迁移学习的基本逻辑到 Transformers 库的版本选择再到完整的微调实操和问题排查最后延伸到大模型时代主流的 LoRA 微调这条链路算是能覆盖 80% 以上的实际项目需求了。我个人在实际操作中的体会是微调这件事本质上比拼的并不是谁对模型架构理解得更深而是谁更能耐心地处理数据、更有条理地排查问题。很多人觉得跑通一个训练脚本就算掌握了迁移学习但真正到了真实业务场景数据分布、标签质量、显存限制、部署环境每一项都可能让你栽跟头。所以如果你看完这篇文章只能记住一个点我希望是遇到问题时不要急着怀疑模型先把数据和环境逐项排查一遍大部分坑都藏在这里。最后再分享一个我最近用得比较多的小技巧。微调一个模型的时候我会同时把训练集的随机抽几条样本在训练前和训练后各推理一遍把结果记在实验笔记里。这比只看 loss 和 acc 直观得多尤其当你调完一轮参数能从具体的文本输出里直接看出模型行为发生了哪些变化——比如是不是学会了不再输出固定话术是不是对某些敏感词的判断变准确了。这种“带人味”的检查方式在模型迭代阶段非常有用建议你也试试。
网站建设高端定制企业官网