开始之前
你需要第 1 课的准备:一个 Hugging Face 账号,以及用 hf auth login 保存好的令牌。要跑 Gemma 2 的示例,还需要你的访问申请已经获批。Transformers 在 Python 3.11 或更高版本、PyTorch 2.6 或更高版本上测试过。PyTorch 是替模型做数值计算的数学库,Transformers 是 Hugging Face 在它之上加载 Hub 模型的库。
pipeline 把每次运行模型都要做的三件事打包在一起:先把输入变成 token,再运行模型,最后把输出变回标签或文字。这个过程叫推理,也就是用训练好的模型处理新的输入,而不是训练它。每个任务,比如 text-classification 或 text-generation,都有自己的 pipeline,正确的步骤已经内置好了。想要更细的控制,Transformers 还有 AutoModelForCausalLM 这样的模型类,对话模板页面用的就是它。pipeline 是更短的路,本课只走这条路。
同样的调用也能处理音频和图片。pipeline 教程用 automatic-speech-recognition 任务和 openai/whisper-large-v3 转写一段语音,用 image-classification 任务和 google/vit-base-patch16-224 给一张照片贴标签。本课只讲文本。
GPU 不是必需的。本课用到的分类器和 GPT-2 都很小,笔记本的 CPU 就跑得动。后面的设备表格会说明,有了 GPU 之后哪些地方会变。
Transformers 在 2026 年 1 月发布了第 5 版。从老教程里抄示例之前,先运行 pip show transformers 看看自己的版本:之后的几次发布提高了最低支持的 Python 版本,也改变了请求已停用的 pipeline 任务时会发生的事。
安装 Transformers,跑通第一个 pipeline
安装页面用的是 uv,一个很快的 Python 包管理器。页面说,如果你更习惯 pip,把每条命令里的 uv 去掉就行。安装步骤最后是一条检查命令,也就是下面代码的最后一行。它会下载默认的情感分析模型,并给一句话打上标签。
第一次调用某个模型时,它的文件会下载到第 1 课说的缓存里,除非你挪过位置,否则就在 ~/.cache/huggingface/hub。之后的调用都从缓存加载,所以只有每个模型第一次运行时要等网络。
每个 pipeline 返回的都是普通的 Python 数据。分类器返回一个字典列表,每个字典有一个 label 和一个 0 到 1 之间的 score。分数接近 1,说明模型对这个标签很有把握。文本生成器返回带 generated_text 键的字典。传入一个输入列表,就会得到一个结果列表,每个输入对应一个结果。
uv venv .env
source .env/bin/activate
uv pip install "transformers[torch]"
python -c "from transformers import pipeline; print(pipeline('sentiment-analysis')('hugging face is the best'))"- 用
uv venv .env创建虚拟环境,再用source .env/bin/activate激活它。在 Windows 上,改为运行.env\Scripts里的 activate 脚本。后面的每条命令都默认环境已经激活。 - 用
uv pip install "transformers[torch]"安装,PyTorch 会一并装好。如果机器没有 NVIDIA GPU,文档给了只用 CPU 的安装方式:先运行uv pip install torch --index-url https://download.pytorch.org/whl/cpu,再运行uv pip install transformers。 - 运行检查命令。文档的示例里,它打印出一条结果:标签是
POSITIVE,分数略低于 1。 - 不用默认模型,自己写明:
pipeline(task="text-classification", model="distilbert/distilbert-base-uncased-finetuned-sst-2-english")。调用时传一个字符串;有好几条输入时,传一个字符串列表。 - 换成文本生成:
pipeline(task="text-generation", model="google/gemma-2-2b"),然后用半句话来调用它。Gemma 2 是受限模型,所以这一步需要已获批的访问权限和保存好的令牌。 - 看结果。文档的示例里,关于烤蛋糕的那句提示词原样返回,后面接着“1. the right ingredients 2. the”。默认会带上提示词,加上
return_full_text=False就只返回新生成的文字。
和指令模型对话
指令模型的名字里常带有 Instruct,它经过进一步训练,能听从请求、进行对话。对话模型接收一个消息列表,每条消息是一个带 role 和 content 的字典。先放一条 user 消息。system 消息可有可无,用来告诉模型该怎样表现。
这段代码就是对话页面自己的示例。它用的是 SmolLM2-1.7B-Instruct,一个 Apache 2.0 许可、不用申请访问的模型。dtype="auto" 会按模型配置里写的精度加载权重,device_map="auto" 会把权重放到找到的最快设备上。后者需要 Accelerate 库,用 pip install -U accelerate 安装。
返回的不是一个简单的字符串。response[0]["generated_text"] 装着整段对话,包括你的消息和新的回复,所以用 [-1]["content"] 读出回答。max_new_tokens=512 限制模型最多新写多少个 token。想继续聊,就拿这个列表,追加下一条 user 消息,再调用一次 pipeline。对话可以一直变长,直到填满模型的上下文窗口(它一次最多能读的 token 数),或者内存用完。
每次调用时,pipeline 都会套用对话模板,也就是模型自己标记“谁说了什么”的方式,用的是模型在训练中学会的控制 token。如表所示,两个出自同一个 Mistral-7B 基础模型的模型,标记对话轮次的方式并不一样。用错了 token,这些模型的表现会大幅变差。
pipeline 还会替你在末尾加上助手回合的开头,这个设置叫 add_generation_prompt。不加的话,模型可能只是接着你的消息往下写。如果最后一条消息的角色是 assistant,pipeline 会把它当成回复的开头,接着往下写。这叫预填充,当你知道回答该怎样开头时很有用。
想不写代码、快速聊几句,运行 transformers chat Qwen/Qwen2.5-0.5B-Instruct 就能在终端里打开对话。它在背后用的是 transformers serve,所以对话页面要求你先把 transformers serve 启动起来。
chat = [
{"role": "system", "content": "You are a helpful science assistant."},
{"role": "user", "content": "Hey, can you explain gravity to me?"}
]
import torch
from transformers import pipeline
pipeline = pipeline(task="text-generation", model="HuggingFaceTB/SmolLM2-1.7B-Instruct", dtype="auto", device_map="auto")
response = pipeline(chat, max_new_tokens=512)
print(response[0]["generated_text"][-1]["content"])| 模型 | 怎样标记用户这一轮 | 怎样标记回复 |
|---|---|---|
| Mistral-7B-Instruct | 消息前面是 [INST],后面是 [/INST] | 紧跟在 [/INST] 后面的普通文字 |
| Zephyr-7B | 消息上一行是 <|user|> | 回复上一行是 <|assistant|> |
文档里 add_generation_prompt 的示例 | 消息前面是 <|im_start|>user,后面是 <|im_end|> | <|im_start|>assistant,由 add_generation_prompt 加上 |
选择设备、精度和批大小
不设置 device 时,pipeline 会用它找到的第一个加速器:通过 CUDA 用 NVIDIA GPU,通过 MPS 用 Apple 芯片的 GPU,或者通过 XPU 用 Intel GPU。这三个分别是各家厂商在自家 GPU 上做计算的途径。一个都没有时,pipeline 才退回到 CPU。如果脚本必须在每台机器上表现一致,就自己指定设备。
内存决定模型能不能跑起来。每个参数都是一个数字,dtype,也就是数字格式,决定它占多大:float32 占 4 个字节,float16 或 bfloat16 占 2 个。
一个 8B 模型,也就是有 80 亿个参数的模型,按对话页面的算法,用 float32 大约要 32GB。半精度能减掉一半。硬件支持的话,bfloat16 比 float16 的取值范围更大。pipeline 教程说,对大多数模型来说,半精度带来的质量损失可以忽略,模型越大损失越小。
默认情况下,Transformers 按模型 config.json 里写的 dtype 加载。想自己选,就传 dtype="auto",或者 torch.bfloat16 这样的具体类型。还想再省,pipeline 也接受用 bitsandbytes 库量化到 8 位或 4 位的模型,通过 model_kwargs 传进去。教程自己的示例就是这样,一次调用加载 google/gemma-7b,用 bfloat16、8 位权重,再加 device_map="auto"。下载大模型之前,本地大模型硬件那一课按模型规模列出了需要的内存。
速度也跟着内存走。模型每写一个 token,都要从内存里把每个活跃参数读一遍。所以对话页面说,提速的办法是量化,或者换内存带宽更高的硬件,单纯加算力帮助不大。
混合专家模型是这条规律的例外。它把层拆成许多专家模块,每个 token 只经过其中几个,所以 Mixtral、Qwen2MoE 和 GPT-OSS 每写一个 token 只读取一小部分参数。它们对内存带宽的要求更低,速度可能超过同样大小的普通模型,不过所有参数仍然都得装进内存。
对话页面还提到一个办法,叫推测解码:先让一个小模型草拟 token,再让大模型检查,这样一步可以接受好几个 token。它对混合专家模型帮助不大,因为每多草拟一个 token,就会唤醒更多参数。
批处理是用 batch_size 让好几条输入一起通过模型。它默认是关的,因为不一定更快。在 CPU 上别用,每个回答都要很快返回时也别用;真要用,就得准备好处理内存不足的错误。先在你自己的模型、数据和硬件上测一测,再决定留不留。
数据集很大时,别给 pipeline 一个大列表,而是给它一个迭代器:一个生成器函数,或者用 KeyDataset 包起来的数据集列。这样 pipeline 会边读边处理,不用先把全部数据放进内存。
| 设置 | 模型在哪里运行 | 什么时候用 |
|---|---|---|
不设置 device | 找到的第一个加速器(CUDA、MPS、XPU),否则用 CPU | 想在任何机器上都用合理的默认值 |
device="cpu" | CPU,即使有 GPU 也不用 | 无论有没有 GPU,每次都要用 CPU 跑 |
device=0 | 第一块 NVIDIA GPU | 一块 GPU 就装得下整个模型 |
device="mps" | Apple 芯片 Mac 的 GPU | 你用的是 M 系列芯片的 Mac |
device_map="auto" | Accelerate 先填满最快的设备,再用 CPU,最后用硬盘 | 模型比一块 GPU 还大,并且已经装好 Accelerate |
Lysandre 的对话命令行用法,和 Andrej Karpathy 对特殊 token 的提醒
Lysandre 是 Hugging Face 的首席开源官。他在 2025 年 5 月在 X 上说,从 4.52 版起,一条 transformers chat 加上模型 id 就够了,生成参数可以直接跟在后面。现在的对话页面把它们写成 key=value 的形式,比如 transformers chat Qwen/Qwen2.5-0.5B-Instruct do_sample=False max_new_tokens=10,transformers chat -h 会列出其余参数。先在这里把提示词调顺,再围绕它写 pipeline 代码。
Andrej Karpathy 是 AI 研究者和教育者,也是 OpenAI 的创始成员之一。他在 2024 年 8 月在 X 上提醒,分词器会从普通文本里解析出特殊 token。用户在你的应用里输入 <|endoftext|>,就可能把一个控制 token 塞进模型的输入,和 SQL 注入很像。他的办法是同时设置 add_special_tokens=False 和 split_special_tokens=True,特殊 token 由你自己的代码添加。对话模型的话,他认为交给对话模板也行。
这个提醒今天仍然成立。在 Transformers 5.22.1 里,分词器参考给 split_special_tokens 的默认值仍是 False。如果你的应用要对用户输入的文字分词,就传入 split_special_tokens=True,再照他说的,把分出来的 token 打印出来看一看。
用户输入的字符串是不可信的数据

X 官方嵌入卡片的截图,拍摄于 2026 年 11 月 5 日,时间为 UTC。X 用“Show more”截断了 Andrej Karpathy 的帖子。点击截图可到 X 上打开原帖。
常见错误
- 不写模型 id。每个任务都会退回到一个默认模型,它未必适合你的文本、你的内存,也未必过得了你的许可证核查。
- 作者还没批准你的申请,或者没有保存令牌,就去调用 Gemma 2。两样都到位之前,下载会一直卡住。
- 让基础模型陪你聊天。
google/gemma-2-2b只会接着文本往下写,它经过对话训练的兄弟是google/gemma-2-2b-it,消息列表只有交给后者才会得到像样的回复。 - 在提示词里手动输入控制 token。错一个 token,模型就偏离了它训练时的格式,所以直接传消息列表。
- 在 CPU 上打开
batch_size,而 pipeline 文档建议在 CPU 上根本不要批处理。 - 设置
trust_remote_code=True却不指定版本。这个参数会运行模型仓库里的 Python 代码,用revision=固定一个提交哈希,那段代码就不会在你不知情时变掉。 - 还没装 Accelerate 就用
device_map="auto"。在同一个环境里运行一次pip install -U accelerate就好了。
自己试一试
在虚拟环境里启动 python,输入下面这几行,它们来自 pipeline 教程。GPT-2 是公开的小模型,不需要令牌,也不需要 GPU。Python 提示符会打印出这次调用返回的四段续写。
from transformers import pipeline
pipeline = pipeline(task="text-generation", model="openai-community/gpt2")
pipeline("the secret to baking a good cake is", num_return_sequences=4, return_full_text=False)- 把这次调用运行两遍。两次的四段续写一样吗?
- 去掉
return_full_text=False,比较一下返回的内容。 - 加载步骤里的 DistilBERT 分类器,传给它三条简短评论组成的列表。哪一条分数最低?
- 把 SmolLM2 的对话分别用
device="cpu"和不设置设备各跑一次,各计时一次回复。 - 在对话末尾加一条以“Answer:”开头的
assistant消息。回复是怎样接着它往下写的? - 照对话页面的做法继续 SmolLM2 的对话:在返回的列表后面追加一条
user消息,再调用一次 pipeline。第二次回复接上第一次了吗? - 运行第 1 课的
hf cache ls。本课新增了哪些模型,每个占多少硬盘?
接下来
现在,凡是你的机器装得下的模型,你都能跑了。装不下的也很多:一个 70B 模型按每个数字 2 个字节算,大约要 140GB,远远超出笔记本的能力。第 3 课用同样的 Hub id 把这些模型交给托管提供商运行,费用记在你的 Hugging Face 账号上。本课的消息列表可以原样沿用,调用时唯一需要的钥匙,就是你在第 1 课保存的令牌。
自测一下
不设置 device 时,pipeline 在哪里运行?
查看答案
B. 在它找到的第一个加速器上,否则在 CPU 上 它先找 CUDA、MPS 或 XPU,一个都没有时才退回到 CPU。
一个 8B 模型的权重用 float32 大约要多少内存?
查看答案
D. 32GB 80 亿个参数,每个 4 字节,大约 32GB,半精度能减掉一半。
想和指令模型对话,要给文本生成 pipeline 传什么?
查看答案
A. 一个消息列表,每条都有 role 和 content pipeline 会把模型的对话模板套到消息列表上,你不用手写控制 token。
什么时候值得打开 batch_size?
查看答案
C. 在 GPU 上、输入长度稳定、并且测过之后 批处理能让 GPU 上的任务变快,但没有保证。文档建议在 CPU 上别用,每个回答都要很快返回时也别用。
常见问题
Transformers pipeline 需要 GPU 吗?
不需要。没有加速器时它就在 CPU 上运行,安装页面也给了只用 CPU 的安装方式。小模型适合在 CPU 上跑,模型一大,内存读取越来越多,速度就慢下来了。参数过了几十亿,GPU 或托管提供商就开始划算了。
怎样找到一个模型需要的任务名?
看模型页面上的任务标签。这个标签就是模型卡里的 pipeline_tag,和 pipeline() 接受的名字一致,比如 text-generation。每个 pipeline 的 API 文档里也列出了它的任务标识。
为什么我的对话模型不听指令,或者说个没完?
通常是因为对话模板没套上,或者套了两次。把消息列表交给 pipeline,让它只格式化一次。如果你自己用 apply_chat_template(tokenize=False) 生成文本,之后分词时要加 add_special_tokens=False。
能离线运行 pipeline 吗?
可以。设置 HF_HUB_OFFLINE=1 之后,这些库就不再访问 Hub,只读取硬盘上已有的文件。如果你直接加载模型类,改为给 from_pretrained 传 local_files_only=True。先在联网时把每个模型跑一次,断网之前文件就已经在了。
资料来源
- Transformers: Pipeline https://huggingface.co/docs/transformers/pipeline_tutorial
- Transformers: Installation https://huggingface.co/docs/transformers/installation
- Transformers: Chat basics https://huggingface.co/docs/transformers/conversations
- Transformers: Chat templates https://huggingface.co/docs/transformers/chat_templating
- Transformers: Loading models https://huggingface.co/docs/transformers/models
- Hugging Face: google/gemma-2-2b model page https://huggingface.co/google/gemma-2-2b
- Hugging Face: HuggingFaceTB/SmolLM2-1.7B-Instruct model page https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct
- Hugging Face: distilbert-base-uncased-finetuned-sst-2-english model page https://huggingface.co/distilbert/distilbert-base-uncased-finetuned-sst-2-english
- Transformers: Tokenizer reference https://huggingface.co/docs/transformers/main_classes/tokenizer
- Transformers release v5.0.0rc0 https://github.com/huggingface/transformers/releases/tag/v5.0.0rc0
- Transformers release v5.0.0 https://github.com/huggingface/transformers/releases/tag/v5.0.0
- Transformers release v5.19.0 https://github.com/huggingface/transformers/releases/tag/v5.19.0
- Transformers release v5.21 https://github.com/huggingface/transformers/releases/tag/v5.21
- Transformers release v5.22.0 https://github.com/huggingface/transformers/releases/tag/v5.22.0
- Lysandre on X: transformers chat from v4.52 https://x.com/LysandreJik/status/1925124636498645407
- Andrej Karpathy on X: special tokens and untrusted user input https://x.com/karpathy/status/1823418177197646104
- Hugging Face on YouTube: The pipeline function https://www.youtube.com/watch?v=tiZFewofSLM

![Lysandre(@LysandreJik)2025 年 5 月 21 日在 X 上发帖:从 v4.52 起,一条“transformers chat [model id]”就够了。对话命令行升级后更简单,也更好配置,任何生成参数(temperature、采样、num beams、重复惩罚、early_stopping)都能直接在命令行上传入](/blog/shots/x-lysandrejik-transformers-chat-cli.webp?v=8510735471d8)
