尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Transformers库入门实战:用Python加载预训练模型跑通分类、生成与微调

发布时间:2026/9/29 18:34:32

资讯中心
01
ARTICLE

Transformers库入门实战:用Python加载预训练模型跑通分类、生成与微调

Transformers库入门实战:用Python加载预训练模型跑通分类、生成与微调
第一次跑通一个预训练大模型其实是有点“上头”的——你只用了几行代码就让一个在百万级语料上训练过的模型开口说话、判断情绪、回答问题。但如果你是从零开始接触这个领域大概率也被卡过模型文件到底从哪来为什么代码第一行就报错别人说的“分词”到底是个什么鬼这篇入门指南我尽量写得像一次真实的上手过程。目标很简单让你用 Python 装好环境、成功调用 Transformers 库里的预训练模型跑通分类、生成、相似度这几个最常见的任务最后还能在个人电脑上做一次最小的微调实验。文章里所有的报错和坑都是我实际踩过的不是文档里抄来的——适合刚接触 Python 不久、对深度学习只有模糊概念、但想赶紧让模型跑起来的人。1. 从裸模型到开箱即用Transformers具体封装了什么先说一个困惑我很久的问题以前那些大模型到底是怎么被普通人用起来的1.1 没有Transformers的时候调一个模型有多痛苦在 Hugging Face 的 Transformers 库流行之前你想用 BERT 跑个文本分类大概要做这么几件事去论文或官方仓库找到模型权重文件的下载链接手动下载几个 GB 的 checkpoint自己写一段加载参数的反序列化代码把输入文本转成能喂给模型的 token id再把数据放到 GPU 上腾挪维度。整个流程下来光是在“让模型跑通”这一步就能耗掉一两天更别说出错之后根本不知道是权重加载的问题还是数据处理的问题。这里打个比方没有 Transformers 库的时候你相当于拿到了一套精装修的图纸和一堆建材得自己从地基开始盖房子有了 Transformers 库以后你拿到的是一个已经住进去就能用的精装公寓——图纸、装修队、家具全部就位你只需要按门铃进去住。1.2 这个库帮你包办了哪几层事情现代的大模型项目本质上绕不开三个模块模型结构定义、分词器、预训练权重。Transformers 库把这三样东西统一成了一个标准的加载管线模型架构你不需要再手写 Transformer 的 attention 层、layer norm、feed forward 这些模块。它帮你把 BERT、GPT、T5、LLaMA 等结构的官方实现都写好了直接通过AutoModelForSequenceClassification这样的类加载。分词器Tokenizer模型吃进去的不是字符串而是一串整数编号。分词器负责把“我喜欢编程”切分成符合词表的子词再映射成 id同时处理 padding、truncation、attention mask 这些细节。权重托管模型权重统一从 Hugging Face Hub 下载缓存到本地固定目录。你只需要写一个模型名比如bert-base-chinese剩下的下载、版本匹配、缓存管理都由库来完成。再加上pipeline这个高层接口很多任务甚至不需要你理解上面的任何细节三行代码就能出结果。这也是为什么现在很多人称它为大模型时代的“标准库”——不只是省事更重要的是统一了生态让一套代码能兼容几千个模型。但这里我想提醒一句上手时用pipeline没问题但千万别长期停留在“只会调 pipeline”的阶段。后面你会逐渐需要理解模型输出张量、自己写推理循环否则一换任务类型就寸步难行。所以本文会把pipeline和底层 API 的代码都给你看一遍让你两条路都走通。2. 环境准备比想象中容易翻车版本、镜像与缓存目录这一节我要先说结论Transformers 库本身的安装很简单难的是它依赖的 PyTorch 环境。大多数报错都发生在“版本组合不对”上。2.1 一套不会打架的版本组合我现在个人电脑上的环境如下稳定用了很长时间你可以直接参考组件推荐版本备注Python3.9 或 3.103.11、3.12 也能用但有些老库的轮子还没跟上PyTorch2.xCPU 版或 CUDA 11.8 / 12.1 版以官网命令为准Transformers4.40 以上太老版本对新模型支持不全Tokenizers跟着 Transformers 自动装单独出问题很少见Datasets2.x可选微调时建议装如果你有 NVIDIA 显卡优先装 CUDA 版的 PyTorch跑大模型的速度是 CPU 的几十倍。如果没显卡也不必劝退——本文的中文文本分类和文本生成任务用 CPU 也能跑只是慢一些。我自己最早就是纯 CPU 环境开始的。2.2 安装的两种姿势与镜像源问题安装命令其实只有一行pip install transformers # 如果你之后要微调建议加装 datasets pip install transformers datasets但真正装的时候你最可能遇到的问题有两个PyTorch 默认装成了 CPU 版或者模型库从 Hugging Face 官方下载超慢。PyTorch 的安装建议去官网根据系统、CUDA 版本生成对应命令不要用pip install torch一把梭。因为那条命令在多数情况下会装成 CPU 版占了好几个 GB后面却发现用不了 GPU还得重装。模型下载慢的问题有两种解决思路。一是设置环境变量指向镜像站在终端执行export HF_ENDPOINThttps://hf-mirror.comWindows 用户则用set HF_ENDPOINThttps://hf-mirror.com二是在下载前先把模型缓存到本地目录之后代码里指定本地路径这样即使网络断了也能重复使用。具体做法后面第 5 节会讲到。2.3 第一次import就报错的常见原因装完库你输入import transformers报错最多的通常是这几种protobuf版本不匹配老版本容易和某些模型组件冲突。解决方式很简单升级到最新版pip install -U protobuf。tokenizers编译失败多见于 Python 版本较新、没有对应预编译轮子的时候。换个 Python 3.10 环境基本能解决。CUDA相关报错一般是 PyTorch 的 CUDA 版本和显卡驱动不匹配。去终端跑一句python -c import torch; print(torch.cuda.is_available())返回True就说明 PyTorch 层没问题。记住一个排查方向报错发生在import transformers阶段八成是依赖库版本问题报错发生在加载模型阶段八成是网络或权重文件问题。这两类问题不要混在一起查否则很容易浪费时间。3. 三行代码跑通AIpipeline带你完成第一次文本分类整个入门流程里最高光的时刻一定是你第一次看到模型输出预测结果。我们直接从这个高光时刻开始。3.1 pipeline新手最友好的入口安装好环境之后打开你的编辑器新建一个 Python 文件写下面三行from transformers import pipeline classifier pipeline(sentiment-analysis, modeluer/roberta-base-finetuned-jd-binary-chinese) result classifier(这手机电池太耐用了一天充一次电就够了) print(result)这段代码干的事加载一个在京东评论语料上微调过的中文情感分类模型然后把那句评论丢进去。输出大概长这样[{label: positive, score: 0.997}]label是分类标签score是置信度。0.997 意味着模型对“正面”这个判断非常有把握。我第一次跑通这段代码是在一台没有 GPU 的旧笔记本上加载模型花了点时间但预测本身只用了不到一秒。当时的感觉就是原来“用大模型”这么简单确实如果你只是想体验一下pipeline就是这么简单。但这只是开始。我问你几个问题你就知道pipeline的边界在哪了——模型判断“正面”的依据是什么如果输入一条更隐晦的中性表达它还能分对么如果输入长度超过模型上限它会怎么处理带着这些问题我们拆开pipeline的盖子看一下。3.2 拆开pipeline看底层到底发生了什么pipeline内部其实帮我们完成了五个步骤加载分词器、加载模型、文本编码、前向传播、输出后处理。如果你自己手动写一遍就能清楚地看到每一层发生了什么from transformers import AutoTokenizer, AutoModelForSequenceClassification import torch model_name uer/roberta-base-finetuned-jd-binary-chinese tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForSequenceClassification.from_pretrained(model_name) text 这手机电池太耐用了一天充一次电就够了 inputs tokenizer(text, return_tensorspt, truncationTrue, max_length128) print(inputs)这一步会输出类似下面的结构{ input_ids: tensor([[101, 6821, 2682, ..., 102]]), attention_mask: tensor([[1, 1, 1, ..., 1]]), token_type_ids: tensor([[0, 0, 0, ..., 0]]) }input_ids就是分词器把“这手机电池太耐用了...”转成的一串整数[101]和[102]是 BERT 类模型固定的开头和结束符。attention_mask是告诉模型哪些 token 是真实文本、哪些是 padding 补位的。拿到这些张量之后再做一次前向传播with torch.no_grad(): outputs model(**inputs) logits outputs.logits predicted_class_id logits.argmax(dim-1).item() print(predicted_class_id) # 1 表示 positivemodel(**inputs)返回的logits一般是个二维张量形状是(1, num_labels)。这里用的是二分类模型所以它的维度是(1, 2)。用argmax取出最大的下标再对应到标签整个推理就完成了。为什么要单独拆开看这一步因为当你以后想同时处理多条文本、想拿到概率分布而不是只拿最大值、想修改模型输出的后处理逻辑你会发现pipeline的定制性不够不如手动写循环来得灵活。这也是从“调用工具”走向“理解模型”的关键一步。4. 换任务也只是换入口文本生成、相似度和问答的调用套路很多人学完一个任务后遇到新的任务又懵了。其实变换任务不外乎换“任务头”和“模型结构”调用套路高度一致。这一节我带你再过几个最常见的方向。4.1 文本生成用GPT风格模型让AI续写如果你想让模型继续写一段话而不是做分类可以用类似下面的代码from transformers import AutoTokenizer, AutoModelForCausalLM import torch model_name uer/gpt2-chinese-cluecorpussmall tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained(model_name) prompt 今天天气不错我跟朋友一起去公园 inputs tokenizer(prompt, return_tensorspt) out model.generate( inputs.input_ids, max_new_tokens50, do_sampleTrue, temperature0.9, top_p0.9, repetition_penalty1.2, ) print(tokenizer.decode(out[0], skip_special_tokensTrue))文本生成和文本分类有一个核心差异分类模型输出的是“在标签分布上取最大”生成模型输出的是“在词表分布上采样一个 token”然后再把这个 token 拼回输入继续预测下一个 token。这一步一步循环采样就是“续写”的本质。上面代码里的几个参数值得解释一下max_new_tokens50新生成的长度上限。注意不是总长度是新增部分的长度。do_sampleTrue允许随机采样。如果不开启模型每次都会选概率最高的 token结果往往比较机械。temperature0.9控制随机程度。数值越高越发散越低越保守。top_p0.9只从概率累积和达到 90% 的 token 里采样剪掉那些概率很低的“尾巴”让生成更稳定。repetition_penalty1.2对重复出现的 token 施加惩罚避免模型陷入“复读机”模式。中文生成模型的输出质量很大程度上取决于底座的语料领域。如果让一个只有三四亿参数的 GPT-2 中文模型写新闻它可能前言不搭后语这不是你的代码问题而是模型本来就不够强。想体验更好的效果可以换Qwen或其他中文大模型语法结构逻辑性会强很多。4.2 语义相似度找出两句话像不像语义相似度是一个嵌入embedding层的任务让模型把每句话映射成一个固定维度的向量再用余弦相似度衡量远近。from transformers import AutoTokenizer, AutoModel import torch import torch.nn.functional as F model_name shibing624/text2vec-base-chinese tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModel.from_pretrained(model_name) def embed(text): inputs tokenizer(text, return_tensorspt, paddingTrue, truncationTrue, max_length128) with torch.no_grad(): outputs model(**inputs) # 取第一个 token (CLS) 的向量做归一化处理 vec outputs.last_hidden_state[:, 0, :] return F.normalize(vec, p2, dim-1) vec1 embed(人工智能的发展前景) vec2 embed(AI 产业的未来趋势) similarity (vec1 vec2.T).item() print(similarity) # 一般会在 0~1 之间这里有个容易搞混的地方BERT 模型的输出包含很多向量接分类任务时常用[CLS]token 的向量接序列标注任务时则要用每个 token 的向量。在语义相似度这种“文本对匹配”场景里最简单的做法就是取[CLS]向量。有些中文语义模型还会建议你用整个序列的 mean pooling效果可能更好——具体以模型卡说明为准。5. 在真实项目中绕不开的五个坑这一节是本文最想让你仔细看的部分。前面那些都是一路顺风的演示但我在真实项目中反复栽过的跟头大部分都在这里了。5.1 模型下载超时与离线加载第一次跑代码时如果网络到 Hugging Face Hub 不稳定你会看到类似Connection error或直接卡在Downloading vocab.txt的界面。解决办法是设置国内镜像源也就是第 2 节提过的HF_ENDPOINT。但还有一种更稳妥的方式把模型预先下载到本地之后完全走离线路径。你可以写一个脚本from huggingface_hub import snapshot_download snapshot_download( repo_iduer/roberta-base-finetuned-jd-binary-chinese, local_dir./models/roberta-jd-chinese, )把脚本跑完之后模型会存到./models/目录之后代码里把模型名替换成这个本地路径即可。这样做的好处有二一是团队协作时别人直接拷目录就能跑不依赖网络二是生产环境不会因为网络抖动而重启任务。5.2 显存不足与设备迁移如果你在 GPU 上跑模型遇到最多的报错就是CUDA out of memory。我的处理顺序是这样的先看看是不是输入批次太大把batch_size降下来实在不行再降低输入长度比如从 512 降到 256最后才考虑更换更小的模型。还有一个很实用的技巧如果模型权重是 fp32占用内存乘二推理时可以换成半精度fp16或四舍五入的8bit量化。代码很简单model AutoModelForSequenceClassification.from_pretrained( model_name, torch_dtypetorch.float16, device_mapauto, )device_mapauto是让库自动把模型塞进可用的设备CPU 上跑时会自动回退。注意不是所有模型都推荐量化特别是你要做微调的话fp16在梯度下降时更容易不稳定。推理场景用它性价比很高。5.3 中文文本乱码与词表问题我第一次用某个英文模型直接跑中文文本输出的结果完全是乱码类似“损Pic吊饰”。这听起来很吓人但其实原因很简单模型分词器的词表里压根没有多少中文字符你输入中文时切分出的很多 token id 在词表里对应的是别的语义模型只能瞎蒙。解决思路是优先选为中文预训练的模型。判断方法很简单——看模型名称有没有chinese关键字或者看模型卡里有没有说明支持中文。如果你非得用英文模型处理中文至少要先过一步繁简转换或考虑换模型而不是硬调代码。5.4 输入长度超过模型上限BERT 类模型一般把输入长度限制在 512 个 token。你直接把一篇 3000 字的文章丢进去会直接报长度错误。这有点像往一个只能装 500 毫升的瓶子里灌 3 升水。tokenizer已经替我们想好了处理方案就是truncation和paddinginputs tokenizer( long_text, truncationTrue, max_length512, paddingTrue, return_tensorspt, )truncationTrue会把长文本截断到 512paddingTrue则会把短文本统一补到相同长度便于批处理。分子两端要不要截断取决于任务类型——分类任务一般保留开头部分就会丢关键信息吗不一定。所以有些任务会用截断到“开头结尾”的方式这个需要你自己调整实验。5.5 生成结果永远一个样如果你跑文本生成发现temperature调到很高输出还是几乎一样或者总在重复某一句话大概率不是模型傻而是参数搭配有问题。do_sample没开启的情况下temperature是无效的——这也是一开始最容易踩的坑模型默认是 greedy 搜索永远选概率最高的 token。开启do_sampleTrue之后temperature才能发挥“调节随机性”的作用top_p才能进一步过滤低概率 token。如果你还遇到了重复repetition_penalty一般设 1.1 到 1.3 就能压住。另外max_new_tokens别设太长太长的生成结果容易在后半段失控可以把长文本生成拆成多段迭代每段生成 50 到 100 个 token下一段带着上一段的输出继续。6. 不换框架不烧钱在个人电脑上完成最小微调实验跑通推理只是第一步。很多时候预训练模型的通用能力不符合你的业务场景比如它把“这游戏真香”分成了负面但你想要的是“真香是正面”。这时候就需要微调。6.1 先判断你的任务需不需要微调不是所有任务都需要微调。比如情感分类这种通用任务直接用一个已经在中文评论上微调过的模型效果就可能够用了。但如果你的文本充满了行业术语、特殊表达比如医疗诊断报告、法律合同段落通用模型很可能理解不了这时微调才有必要。原则是先用现成模型跑一遍看效果差在哪再决定要不要微调。不要一上来就训练模型那是拿大炮打蚊子。6.2 最小可见的微调代码训练文本分类模型如果你决定微调下面的代码可以帮你快速跑通一个最小实验。假设你有一个简单的标注数据集每行是一条文本和一个标签0 或 1我用 CSV 格式演示from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments from datasets import Dataset import pandas as pd model_name bert-base-chinese tokenizer AutoTokenizer.from_pretrained(model_name) df pd.read_csv(train_data.csv) # 列名text, label dataset Dataset.from_pandas(df) def tokenize_function(examples): return tokenizer(examples[text], truncationTrue, max_length128) tokenized_dataset dataset.map(tokenize_function, batchedTrue) model AutoModelForSequenceClassification.from_pretrained(model_name, num_labels2) training_args TrainingArguments( output_dir./results, num_train_epochs3, per_device_train_batch_size8, learning_rate2e-5, evaluation_strategyepoch, logging_dir./logs, save_total_limit2, ) trainer Trainer( modelmodel, argstraining_args, train_datasettokenized_dataset, ) trainer.train()这段代码重点看后面三个参数num_train_epochs3训练轮数。个人经验是 2 到 3 轮就够再多容易过拟合。learning_rate2e-5微调预训练模型时学习率要比从零训练小很多。习惯用 1e-5 到 3e-5。per_device_train_batch_size8单卡批大小。显存小就调成 4 或 2。微调的过程本质上只是让大模型“偏科”——它的原有限知识没有丢失只是针对你的数据分布更新了最后的分类层和少量中间层参数。这也是为什么微调不需要从零训练那么大的数据和算力。6.3 让微调少烧钱、更省心的小技巧在资源有限的情况下我常用的办法是冻结部分参数for param in model.bert.parameters(): param.requires_grad False只训练分类头参数量少了几个数量级显存占用和训练时间都会明显降低适合快速验证“这个数据集到底能不能训练出效果”。等验证通过了再放开全量参数继续调几轮。另外early_stopping很有用。在 TrainingArguments 里传入load_best_model_at_endTrue和metric_for_best_model就能在验证集效果不再提升时果断停止。跑微调不像推理纯 CPU 训练一个小模型也得半小时起步能省十分钟都是好的。说到底Transformers 库把“调用大模型”这件事的门槛降到了接近零但真正让你的代码能稳定用在真实项目里的还是你对模型边界、数据格式、硬件限制这些底层细节的把握。我特别建议你按这条路径走一遍先跑pipeline建立直觉再亲手写一遍AutoTokenizer的推理循环然后换任务类型最后用一个小数据集做微调实验。走完这一圈你对“Python 调用预训练大模型”的理解会比看一百篇教程都扎实。最后分享一个我自己的习惯每次换新模型我都会先把它的 model card模型卡完整读一遍重点看它支持的输入语言、最大长度、推荐参数。大多数玄学报错其实在模型卡里都有答案。这个习惯帮我节省了大量无效查错时间也推荐给你。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。