Transformers
https://huggingface.co/docs/transformers/main/index
Transformers acts as the model-definition framework for state-of-the-art machine learning models in text, computer vision, audio, video, and multimodal model, for both inference and training.
It centralizes the model definition so that this definition is agreed upon across the ecosystem. transformers is the pivot across frameworks: if a model definition is supported, it will be compatible with the majority of training frameworks (Axolotl, Unsloth, DeepSpeed, FSDP, PyTorch-Lightning, …), inference engines (vLLM, SGLang, TGI, …), and adjacent modeling libraries (llama.cpp, mlx, …) which leverage the model definition from transformers.
We pledge to help support new state-of-the-art models and democratize their usage by having their model definition be simple, customizable, and efficient.
There are over 1M+ Transformers model checkpoints on the Hugging Face Hub you can use.
Explore the Hub today to find a model and use Transformers to help you get started right away.
Explore the Models Timeline to discover the latest text, vision, audio and multimodal model architectures in Transformers.
Features
Transformers provides everything you need for inference or training with state-of-the-art pretrained models. Some of the main features include:
- Pipeline: Simple and optimized inference class for many machine learning tasks like text generation, image segmentation, automatic speech recognition, document question answering, and more.
- Trainer: A comprehensive trainer that supports features such as mixed precision, torch.compile, and FlashAttention for training and distributed training for PyTorch models.
- generate: Fast text generation with large language models (LLMs) and vision language models (VLMs), including support for streaming and multiple decoding strategies.
Design
Read our Philosophy to learn more about Transformers’ design principles.
Transformers is designed for developers and machine learning engineers and researchers. Its main design principles are:
- Fast and easy to use: Every model is implemented from only three main classes (configuration, model, and preprocessor) and can be quickly used for inference or training with Pipeline or Trainer.
- Pretrained models: Reduce your carbon footprint, compute cost and time by using a pretrained model instead of training an entirely new one. Each pretrained model is reproduced as closely as possible to the original model and offers state-of-the-art performance.

Learn
If you’re new to Transformers or want to learn more about transformer models, we recommend starting with the LLM course. This comprehensive course covers everything from the fundamentals of how transformer models work to practical applications across various tasks. You’ll learn the complete workflow, from curating high-quality datasets to fine-tuning large language models and implementing reasoning capabilities. The course contains both theoretical and hands-on exercises to build a solid foundational knowledge of transformer models as you learn.
https://huggingface.co/docs/transformers/main/chat_templating
Using apply_chat_template
The input to apply_chat_template should be structured as a list of dictionaries with role and content keys. The role key specifies the speaker, and the content key contains the message. The common roles are:
userfor messages from the userassistantfor messages from the modelsystemfor directives on how the model should act (usually placed at the beginning of the chat)
apply_chat_template takes this list and returns a formatted sequence. Set tokenize=True if you want to tokenize the sequence.
import torch
from transformers import AutoModelForCausalLM, AutoTokenizertokenizer = AutoTokenizer.from_pretrained("HuggingFaceH4/zephyr-7b-beta")
model = AutoModelForCausalLM.from_pretrained("HuggingFaceH4/zephyr-7b-beta", device_map="auto", dtype=torch.bfloat16)messages = [{"role": "system", "content": "You are a friendly chatbot who always responds in the style of a pirate",},{"role": "user", "content": "How many helicopters can a human eat in one sitting?"},]
tokenized_chat = tokenizer.apply_chat_template(messages, tokenize=True, add_generation_prompt=True, return_tensors="pt")
print(tokenizer.decode(tokenized_chat[0]))
<|system|>
You are a friendly chatbot who always responds in the style of a pirate</s>
<|user|>
How many helicopters can a human eat in one sitting?</s>
<|assistant|>
Pass the tokenized chat to generate() to generate a response.
outputs = model.generate(tokenized_chat, max_new_tokens=128)
print(tokenizer.decode(outputs[0]))
<|system|>
You are a friendly chatbot who always responds in the style of a pirate</s>
<|user|>
How many helicopters can a human eat in one sitting?</s>
<|assistant|>
Matey, I'm afraid I must inform ye that humans cannot eat helicopters. Helicopters are not food, they are flying machines. Food is meant to be eaten, like a hearty plate o' grog, a savory bowl o' stew, or a delicious loaf o' bread. But helicopters, they be for transportin' and movin' around, not for eatin'. So, I'd say none, me hearties. None at all.
https://github.com/fanqingsong/LLM_transformer_helloworld
对话模型推理
# -*- coding: utf-8 -*- """ 仅此文件允许考生修改: - 请在下列函数的函数体内完成实现。 - 不要改动函数名与参数签名。 - 你可以新增少量辅助函数。 """from typing import List import torch from transformers import AutoTokenizer, AutoModelForCausalLM# ============================================================ # 第一部分:Prompt 定义 # ============================================================ def build_system_prompt() -> str:"""考生实现:定义 system prompt- 返回一个 system prompt,要求模型以"[Answer]: xxxx"的格式给出最终数值。System Prompt 的作用:1. 定义模型的身份和角色(数学助手)2. 指导模型的推理过程(逐步分析、解题思路)3. 规范模型的输出格式([Answer]: 数值)为什么要用 [Answer]: 格式?- 便于评测程序从模型输出中提取正确答案- 统一答案格式,避免模型输出过多解释性文字- 符合测试数据的标准格式要求"""# ======== 考生实现区域(可修改) ========# System Prompt 定义:指导模型如何回答数学问题# 关键点:必须包含 [Answer]: 格式的要求,这是评测程序提取答案的标准system_prompt = """你是一个数学助手,擅长解决各种数学问题。请仔细分析问题,逐步推理,并最终以 [Answer]: 数值 的格式给出答案。要求: 1. 仔细阅读题目,理解题意 2. 逐步分析解题思路 3. 进行必要的计算 4. 最终答案必须以 [Answer]: 数值 的格式给出请开始解题。"""return system_prompt# ======== 考生实现区域(可修改) ========# ============================================================ # 第二部分:模板拼装 # ============================================================ def apply_chat_template_single(tokenizer: AutoTokenizer,system_prompt: str,problem: str, ) -> str:"""考生实现:将单个问题转换为模型输入文本- 使用 tokenizer.apply_chat_template 构造对话- 返回拼装好的文本字符串参数说明:tokenizer: Qwen3 模型的 tokenizer,包含特殊 token 和模板定义system_prompt: 系统提示词,定义模型角色和输出格式problem: 用户问题(如 "12 + 35")返回值:完整格式化后的对话文本,包含 system、user、assistant 标记Chat Template 的作用:transformers 库的 tokenizer.apply_chat_template 会根据模型类型自动构造符合该模型预期的对话格式。对于 Qwen 模型,它会把 messages 列表转换为:<|system|>你是一个数学助手...<|user|>12 + 35<|assistant|>这样的格式。"""# ======== 考生实现区域(可修改) ========# 构造消息列表:包含系统提示和用户问题# 消息格式:每个消息是一个字典,包含 role(角色)和 content(内容)# - "system": 定义模型行为# - "user": 用户输入的问题messages = [{"role": "system", "content": system_prompt},{"role": "user", "content": problem},]# 应用聊天模板,将消息列表转换为模型可理解的文本格式rendered = tokenizer.apply_chat_template(messages, # 消息列表tokenize=False, # 不进行 tokenize,返回原始字符串而不是 token IDs# 这样可以在调试时看到完整的文本内容add_generation_prompt=True, # 添加 <|assistant|> 标记,引导模型生成回复# 如果没有这个标记,模型不知道要在哪里开始生成enable_thinking=True, # 启用思考标签支持# 允许模型输出 <think>...</think># 模型会在 <> 标签内进行推理,评测程序会自动移除这部分内容 )return rendered# ======== 考生实现区域(可修改) ========# ============================================================ # 第三部分:核心推理实现 # ============================================================ def generate_single(model: AutoModelForCausalLM,tokenizer: AutoTokenizer,rendered_text: str,max_new_tokens: int,do_sample: bool, ) -> torch.Tensor:"""考生实现:单条推理- 将文本 tokenize 后送入模型生成- 返回包含输入和输出的完整 token 序列参数说明:model: Qwen3 预训练模型,用于文本生成tokenizer: 用于将文本转换为 token IDsrendered_text: 已格式化的完整对话文本(包含 system、user、assistant 标记)max_new_tokens: 生成的最大新 token 数量(不包括输入长度)do_sample: 是否使用采样(True=随机采样,False=贪心解码)返回值:torch.Tensor,形状为 [1, seq_len],包含输入+新生成的完整序列注意事项:1. 返回的是包含输入的完整序列(evaluate.py 会提取新生成的部分)2. 使用 .to(model.device) 确保输入在正确的设备上(CPU/GPU/NPU)3. 使用 model.generate() 的默认参数,模型会自动处理特殊 token"""# ======== 考生实现区域(可修改) ========# 步骤 1:将文本编码为 token IDs# - tokenizer.encode() 将字符串转换为整数列表# - return_tensors="pt" 返回 PyTorch 张量# - .to(model.device) 将张量移动到模型所在的设备(CPU/GPU/NPU)inputs = tokenizer.encode(rendered_text, return_tensors="pt").to(model.device)# 步骤 2:使用模型生成文本# - model.generate() 会自动生成新的 token# - 返回的 outputs 包含完整的序列:输入 + 新生成的 token# - 评测程序会从 outputs 中提取新生成的部分outputs = model.generate(inputs, # 输入 token IDsmax_new_tokens=max_new_tokens, # 最多生成多少个新 tokendo_sample=do_sample, # 采样模式:True=随机采样(更灵活),False=贪心(更确定) )return outputs# ======== 考生实现区域(可修改) ========def generate_batch(model: AutoModelForCausalLM,tokenizer: AutoTokenizer,rendered_texts: List[str],max_new_tokens: int,do_sample: bool, ) -> List[torch.Tensor]:"""考生实现:批量推理- 一次处理多个问题,提高效率- 返回所有批次的输出列表参数说明:model: Qwen3 预训练模型tokenizer: 用于编码文本rendered_texts: 多个已格式化的对话文本列表max_new_tokens: 生成的最大新 token 数量do_sample: 是否使用采样返回值:List[torch.Tensor],每个元素是一个批次的输出批次形状为 [batch_size, seq_len]批量处理的优势:1. 并行处理:GPU 可以同时处理多条数据2. 减少数据传输:一次 GPU 调用处理多条3. 提高吞吐量:相比逐条处理能获得 3+ 倍加速实现要点:1. 使用循环分批处理,避免一次性处理过多数据导致内存溢出2. 使用 padding=True 确保同一批次内序列长度一致3. 使用 attention_mask 告诉模型哪些 token 是 padding,哪些是真实内容4. 使用 torch.no_grad() 节省显存(推理时不需要梯度)"""# ======== 考生实现区域(可修改) ======== all_outputs = [] # 存储所有批次的输出batch_size: int = 4 # 批次大小:一次处理 4 条数据# 可以调整:太小效率低,太大可能内存不足# 循环处理:每次处理一个批次# range(0, len(rendered_texts), batch_size) 生成:0, 4, 8, 12, ...for i in range(0, len(rendered_texts), batch_size):# 提取当前批次:rendered_texts[i:i+batch_size]# 例如:如果 i=0, batch_size=4,则提取第 0, 1, 2, 3 条batch_texts = rendered_texts[i:i + batch_size]# 步骤 1:对批次进行编码和填充# tokenizer() 可以将多条文本同时编码,并自动填充到相同长度# - batch_texts: 多条文本(列表)# - padding=True: 短序列会填充到和最长序列一样长# - truncation=True: 超长序列会被截断# - 返回的 inputs 包含 input_ids 和 attention_maskinputs = tokenizer(batch_texts, # 多条文本(如 ["问题1", "问题2", "问题3", "问题4"])return_tensors="pt", # 返回 PyTorch 张量padding=True, # 自动填充到相同长度truncation=True # 超长序列截断(防止溢出)).to(model.device) # 移动到模型设备# 步骤 2:批量生成文本# 使用 torch.no_grad() 禁用梯度计算,节省显存并提高速度 with torch.no_grad():outputs = model.generate(inputs.input_ids, # 编码后的 token IDs,形状 [batch_size, seq_len]attention_mask=inputs.attention_mask, # 注意力掩码,标记哪些是真实内容(1),哪些是填充(0)max_new_tokens=max_new_tokens, # 最多生成多少个新 tokendo_sample=do_sample, # 采样模式pad_token_id=tokenizer.eos_token_id # 指定填充 token 的 ID# 注意:这里没有使用 pad_token_id=tokenizer.pad_token_id# 因为 Qwen 模型可能没有 pad_token,使用 eos_token_id 作为替代 )# 将当前批次的输出添加到总结果中 all_outputs.append(outputs)# 返回所有批次的输出列表# 例如:如果 10 条数据分成 3 批,则返回 [batch1_output, batch2_output, batch3_output]# evaluate.py 会将这些批次的结果合并到一起return all_outputs# ======== 考生实现区域(可修改) ========
嵌入模型
# -*- coding: utf-8 -*- """ 仅此文件允许考生修改: - 请在下列函数的函数体内完成实现。 - 不要改动函数名与参数签名。 - 你可以新增少量辅助函数。 """import torch import torch.nn.functional as F from transformers import AutoTokenizer, AutoModel# ============================================================ # 相似度计算函数 # ============================================================ def student_compute_similarity(text1: str, text2: str, model: AutoModel, tokenizer: AutoTokenizer) -> float:"""考生实现:计算两个文本之间的相似度参数:text1: 第一个文本字符串(如 "12 + 35")text2: 第二个文本字符串(如 "35 + 12")model: 预加载的 Qwen3-Embedding 模型(评测程序提供)tokenizer: 预加载的 tokenizer(评测程序提供)返回:相似度值(0.0 到 1.0 之间的浮点数)1.0 表示完全相同,0.0 表示完全不同要求:- 使用传入的 model 和 tokenizer,不要自己加载模型- 实现 last-token pooling(取最后一个 token 的隐藏状态作为句子表示)- 必须使用左侧 padding(padding_side="left")- L2 归一化(将向量标准化为单位向量)- 计算余弦相似度(归一化向量的点积)- 不得使用 sentence_transformers相似度计算原理:1. 将文本编码为向量(embedding)2. Last-token pooling:取最后一个 token 的隐藏状态作为句子表示3. L2 归一化:将向量标准化为单位向量4. 余弦相似度:计算两个归一化向量的点积(cos(θ) 的值域为 [-1, 1])为什么使用 last-token pooling?- Embedding 模型在训练时,最后一个 token 包含了整个句子的语义信息- 相比平均 pooling 或 CLS token,last-token 能更好地捕捉句子级语义"""# ======== 考生实现区域(可修改) ========# 步骤 1:获取模型所在的设备(CPU/GPU/NPU)# next(model.parameters()) 获取模型的第一个参数,.device 获取其设备# 这样可以确保输入张量与模型在同一设备上device = next(model.parameters()).device# 步骤 2:准备输入文本列表# 将两个文本放入列表,以便批量处理texts = [text1, text2]# 步骤 3:使用 tokenizer 编码文本# padding=True: 将短序列填充到最长序列的长度# truncation=True: 超长序列截断到 max_length# max_length=512: 最大序列长度(典型的 BERT 等模型长度)# return_tensors="pt": 返回 PyTorch 张量# padding_side="left": 在左侧填充(重要!)# 为什么使用左侧 padding?# - 因为使用 last-token pooling,我们需要保证最后一个 token 是真实的文本 token# - 如果在右侧 padding,最后一个 token 会是填充 token,失去语义信息inputs = tokenizer(texts, # 文本列表:["12 + 35", "35 + 12"]padding=True, # 自动填充到相同长度truncation=True, # 超长序列截断max_length=512, # 最大长度return_tensors="pt", # 返回 PyTorch 张量padding_side="left" # 关键:左侧填充).to(device) # 移动到模型设备# 步骤 4:获取模型输出的嵌入向量# 使用 torch.no_grad() 禁用梯度计算,节省显存并提高速度 with torch.no_grad():# 模型前向传播:输入 token IDs,输出隐藏状态# outputs.last_hidden_state 形状: [batch_size=2, seq_len, hidden_dim]outputs = model(**inputs)# Last-token pooling:取最后一个 token 的隐藏状态作为句子表示# last_hidden_state 形状: [2, seq_len, hidden_dim]# 例如:[[[token1], [token2], [token3]], [[token4], [token5], [token6]]]# [:, -1, :] 表示取每一行的最后一个 token# embeddings 形状: [2, hidden_dim]# 例如:[[token3], [token6]]last_hidden_state = outputs.last_hidden_stateembeddings = last_hidden_state[:, -1, :] # 索引 -1 表示最后一个元素# 步骤 5:L2 归一化# 将向量标准化为单位向量(长度为 1)# 公式:v_normalized = v / ||v||# F.normalize(..., p=2, dim=1):# - p=2: 使用 L2 范数(欧氏距离)# - dim=1: 在 hidden_dim 维度上归一化# 归一化后的向量满足:||v|| = 1# embeddings 形状保持不变: [2, hidden_dim]embeddings = F.normalize(embeddings, p=2, dim=1)# 步骤 6:计算余弦相似度# 对于归一化的向量 a, b,余弦相似度 = a · b(点积)# 如果 a 和 b 都是单位向量,则 cos(θ) = a · b# - 如果 a 和 b 完全相同:a · b = 1# - 如果 a 和 b 垂直:a · b = 0# - 如果 a 和 b 相反:a · b = -1# torch.dot(a, b) 计算向量点积# .item() 将标量张量转换为 Python float# embeddings[0] 是 text1 的嵌入,embeddings[1] 是 text2 的嵌入similarity = torch.dot(embeddings[0], embeddings[1]).item()# similarity 的范围:[0, 1],因为所有向量都是正方向(经过归一化后的嵌入向量)return similarity# ======== 考生实现区域(可修改) ========def compute_similarity(text1: str, text2: str, model: AutoModel, tokenizer: AutoTokenizer) -> float:"""评测程序调用的接口函数"""return student_compute_similarity(text1, text2, model, tokenizer)
