> ## Content Index
> Fetch the complete content index at: https://blog.vercanti.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# HuggingFace Transformers 完全指南
- URL: https://blog.vercanti.com/huggingface-transformers-wan-quan-zhi-nan/
- Published: 2026-08-28T14:35:40.000Z
- Updated: 2026-08-28T14:59:19.000Z
- Description: HuggingFace Transformers 是目前最主流的预训练模型工具库，提供数千个在 Hugging Face Hub 上发布的预训练模型，覆盖 NLP、计算机视觉、语音、多模态等任务。它的核心价值在于：一套统一 API 驯服从 BERT 到 LLaMA 的所有主流架构，无需了解每种架构的内部细节。 对比主要替代方案： 适合场景：需要在本地运行开源模型（Llama、Mistral、Qwen）、Fine-tuning 已有模型、使用 BERT 类模型做文本分类 / NER / 问答。不适合场景：只需调用 GPT-4 等闭源 API（用 OpenA
- Author: yellowdog
- Tags: 机器学习

> 官方文档：<https://huggingface.co/docs/transformers/>  
> 适用版本：5.8.0（2026-05-07 核实）

## 概述

HuggingFace Transformers 是目前最主流的预训练模型工具库，提供数千个在 Hugging Face Hub 上发布的预训练模型，覆盖 NLP、计算机视觉、语音、多模态等任务。它的核心价值在于：一套统一 API 驯服从 BERT 到 LLaMA 的所有主流架构，无需了解每种架构的内部细节。

对比主要替代方案：

- **OpenAI Python SDK**：只能调用 OpenAI 闭源模型，无法在本地运行开源模型
- **sentence-transformers**：专注于 Embedding，不覆盖生成、分类等宽泛任务
- **LiteLLM**：聚合各厂商 API，依赖外部服务，不支持本地推理

适合场景：需要在本地运行开源模型（Llama、Mistral、Qwen）、Fine-tuning 已有模型、使用 BERT 类模型做文本分类 / NER / 问答。不适合场景：只需调用 GPT-4 等闭源 API（用 OpenAI SDK 更简单）。

---

## 安装

```python
pip install transformers torch          # CPU / CUDA
pip install transformers torch --index-url https://download.pytorch.org/whl/cu118  # CUDA 11.8
pip install accelerate datasets         # 训练与数据处理
pip install bitsandbytes                # 4/8-bit 量化

```

---

## pipeline — 一行完成推理

`pipeline()` 是 Transformers 最简洁的推理接口，屏蔽了 tokenize → forward → decode 的细节。

### pipeline()

```python
transformers.pipeline(
    task: str,
    model: str | PreTrainedModel = None,
    config: str | PreTrainedConfig = None,
    tokenizer: str | PreTrainedTokenizer = None,
    feature_extractor: str | FeatureExtractionMixin = None,
    image_processor: str | BaseImageProcessor = None,
    processor: str | ProcessorMixin = None,
    revision: str = "main",
    use_fast: bool = True,
    token: str | bool = None,
    device: int | str | torch.device = None,
    device_map: str | dict = None,
    dtype: str | torch.dtype = None,
    trust_remote_code: bool = False,
    model_kwargs: dict[str, Any] = None,
    **kwargs
) -> Pipeline

```

| 参数                  | 类型                            | 默认值          | 说明                                                           |                                                         |
| ------------------- | ----------------------------- | ------------ | ------------------------------------------------------------ | ------------------------------------------------------- |
| task                | str                           | 必须           | 任务字符串，见下表；决定返回哪种 Pipeline 实例                                 |                                                         |
| model               | str \| PreTrainedModel        | None         | Hub 模型 ID、本地路径或已加载的模型实例；None 时使用各任务默认模型                      |                                                         |
| config              | str \| PreTrainedConfig       | None         | 模型配置；None 时从 model 自动推断                                      |                                                         |
| tokenizer           | str \| PreTrainedTokenizer    | None         | 分词器；None 时自动加载                                               |                                                         |
| feature\_extractor  | str \| FeatureExtractionMixin | None         | 语音 / 视觉任务的特征提取器                                              |                                                         |
| image\_processor    | str \| BaseImageProcessor     | None         | 视觉 / 多模态任务的图像处理器                                             |                                                         |
| processor           | str \| ProcessorMixin         | None         | 多模态任务的统一处理器                                                  |                                                         |
| revision            | str                           | "main"       | Hub 上的分支、tag 或 commit id                                     |                                                         |
| use\_fast           | bool                          | True         | 优先使用 Rust 实现的快速分词器（PreTrainedTokenizerFast）                  |                                                         |
| token               | str \| bool                   | None         | HuggingFace Hub 访问 token；True 则使用 hf\_auth\_login 已存储的 token |                                                         |
| device              | int \| str                    | torch.device | None                                                         | 推理设备；"cpu" / "cuda" / "cuda:1" / "mps"；与 device\_map 互斥 |
| device\_map         | str \| dict                   | None         | 设备映射，"auto" 自动跨 GPU / CPU 分片（依赖 accelerate）；与 device 互斥      |                                                         |
| dtype               | str \| torch.dtype            | None         | 模型精度；torch.float16 / torch.bfloat16 / "auto"                 |                                                         |
| trust\_remote\_code | bool                          | False        | 允许执行 Hub 上的自定义建模代码，仅对可信仓库开启                                  |                                                         |
| model\_kwargs       | dict                          | None         | 透传给 model.from\_pretrained() 的额外参数（如 load\_in\_8bit=True）    |                                                         |

#### 支持的任务字符串

**语音（Audio）**

| task 字符串                           | Pipeline 类                          |
| ---------------------------------- | ----------------------------------- |
| "audio-classification"             | AudioClassificationPipeline         |
| "automatic-speech-recognition"     | AutomaticSpeechRecognitionPipeline  |
| "text-to-audio" / "text-to-speech" | TextToAudioPipeline                 |
| "zero-shot-audio-classification"   | ZeroShotAudioClassificationPipeline |

**计算机视觉（Vision）**

| task 字符串                         | Pipeline 类                          |
| -------------------------------- | ----------------------------------- |
| "depth-estimation"               | DepthEstimationPipeline             |
| "image-classification"           | ImageClassificationPipeline         |
| "image-feature-extraction"       | ImageFeatureExtractionPipeline      |
| "image-segmentation"             | ImageSegmentationPipeline           |
| "image-text-to-text"             | ImageTextToTextPipeline             |
| "keypoint-matching"              | KeypointMatchingPipeline            |
| "mask-generation"                | MaskGenerationPipeline              |
| "object-detection"               | ObjectDetectionPipeline             |
| "video-classification"           | VideoClassificationPipeline         |
| "zero-shot-image-classification" | ZeroShotImageClassificationPipeline |
| "zero-shot-object-detection"     | ZeroShotObjectDetectionPipeline     |

**自然语言处理（NLP）**

| task 字符串                                     | Pipeline 类                        |
| -------------------------------------------- | --------------------------------- |
| "fill-mask"                                  | FillMaskPipeline                  |
| "ner" / "token-classification"               | TokenClassificationPipeline       |
| "sentiment-analysis" / "text-classification" | TextClassificationPipeline        |
| "text-generation"                            | TextGenerationPipeline            |
| "summarization"                              | SummarizationPipeline             |
| "translation"                                | TranslationPipeline               |
| "question-answering"                         | QuestionAnsweringPipeline         |
| "table-question-answering"                   | TableQuestionAnsweringPipeline    |
| "document-question-answering"                | DocumentQuestionAnsweringPipeline |
| "feature-extraction"                         | FeatureExtractionPipeline         |
| "zero-shot-classification"                   | ZeroShotClassificationPipeline    |

#### 示例

```python
from transformers import pipeline

# 最小示例：情感分析
clf = pipeline("sentiment-analysis")
result = clf("This movie is fantastic!")
# [{'label': 'POSITIVE', 'score': 0.9998}]

# 指定模型 + GPU + 半精度
gen = pipeline(
    "text-generation",
    model="meta-llama/Llama-3.2-1B-Instruct",
    device=0,
    dtype="auto",
    token=True,               # 需要 HF 访问 token
    trust_remote_code=True,
)
output = gen("Once upon a time", max_new_tokens=100)

# 批量处理（传入列表）
ner = pipeline("ner", model="dslim/bert-base-NER")
results = ner(["Alice lives in Paris", "Bob works at Google"])

# 语音识别
asr = pipeline("automatic-speech-recognition", model="openai/whisper-base")
transcription = asr("audio.wav")
# {'text': '...'}

# 零样本分类（不需要重新训练）
classifier = pipeline("zero-shot-classification")
classifier(
    "I need to cancel my subscription",
    candidate_labels=["billing", "technical support", "account management"],
)

```

---

## Auto 类 — 自动加载模型与分词器

Auto 类根据模型名称或本地路径自动选择正确的架构类，是加载预训练模型的推荐方式。

### AutoTokenizer.from\_pretrained()

```python
AutoTokenizer.from_pretrained(pretrained_model_name_or_path, **kwargs)

```

| 参数                                | 类型               | 默认值    | 说明                                      |
| --------------------------------- | ---------------- | ------ | --------------------------------------- |
| pretrained\_model\_name\_or\_path | str \| PathLike  | 必须     | Hub 模型 ID（如 "bert-base-uncased"）或本地目录路径 |
| cache\_dir                        | str \| PathLike  | None   | 缓存目录；默认 \~/.cache/huggingface/hub       |
| force\_download                   | bool             | False  | 忽略缓存，强制重新下载                             |
| revision                          | str              | "main" | Hub 上的分支、tag 或 commit id                |
| trust\_remote\_code               | bool             | False  | 允许执行仓库中的自定义分词器代码                        |
| use\_fast                         | bool             | True   | 优先使用 Rust 快速实现（PreTrainedTokenizerFast） |
| proxies                           | dict\[str, str\] | None   | 代理配置，如 {'http': '127.0.0.1:7890'}       |
| token                             | str \| bool      | None   | Hub 访问 token，用于访问私有模型                   |

```python
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased")

# 编码文本
inputs = tokenizer("Hello, world!", return_tensors="pt")
# {'input_ids': tensor(...), 'attention_mask': tensor(...)}

# 批量编码（自动 padding）
inputs = tokenizer(
    ["Hello world", "How are you?"],
    padding=True,
    truncation=True,
    max_length=128,
    return_tensors="pt",
)

# 保存到本地（用于离线部署）
tokenizer.save_pretrained("./my_tokenizer")

```

### AutoModel.from\_pretrained()

```python
AutoModel.from_pretrained(pretrained_model_name_or_path, **kwargs)

```

| 参数                                | 类型                 | 默认值    | 说明                              |
| --------------------------------- | ------------------ | ------ | ------------------------------- |
| pretrained\_model\_name\_or\_path | str \| PathLike    | 必须     | Hub 模型 ID 或本地路径                 |
| cache\_dir                        | str \| PathLike    | None   | 缓存目录                            |
| force\_download                   | bool               | False  | 强制重新下载                          |
| revision                          | str                | "main" | 版本标识符                           |
| trust\_remote\_code               | bool               | False  | 允许自定义建模代码                       |
| device\_map                       | str \| dict        | None   | 设备映射；"auto" 自动多 GPU 分片          |
| return\_unused\_kwargs            | bool               | False  | 返回未被模型使用的额外 kwargs              |
| low\_cpu\_mem\_usage              | bool               | False  | 减少 CPU 内存使用，加载大模型时建议开启          |
| torch\_dtype                      | torch.dtype \| str | None   | 加载精度；"auto" 使用模型原始精度            |
| load\_in\_8bit                    | bool               | False  | 8-bit 量化加载（需要 bitsandbytes）     |
| load\_in\_4bit                    | bool               | False  | 4-bit NF4 量化加载（需要 bitsandbytes） |

```python
from transformers import AutoModel, AutoModelForSequenceClassification, AutoModelForCausalLM
import torch

# 加载编码器（BERT 类）
model = AutoModel.from_pretrained("google-bert/bert-base-uncased")

# 分类任务：编码器 + 分类头
clf_model = AutoModelForSequenceClassification.from_pretrained(
    "distilbert-base-uncased-finetuned-sst-2-english"
)

# 生成任务：解码器（LLM）
llm = AutoModelForCausalLM.from_pretrained(
    "microsoft/phi-2",
    torch_dtype=torch.float16,
    device_map="auto",          # 自动多 GPU 分片
    low_cpu_mem_usage=True,
)

# 4-bit 量化（减少 ~75% 显存）
llm_4bit = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-3.2-8B-Instruct",
    load_in_4bit=True,
    device_map="auto",
    token=True,
)

# 保存模型
model.save_pretrained("./saved_model")

```

#### 常用 AutoModel 子类

| 类名                                 | 适用任务          | 代表模型                        |
| ---------------------------------- | ------------- | --------------------------- |
| AutoModelForSequenceClassification | 文本分类、情感分析     | BERT, RoBERTa, DistilBERT   |
| AutoModelForTokenClassification    | NER、词性标注      | BERT, DeBERTa               |
| AutoModelForQuestionAnswering      | 抽取式问答         | BERT, ELECTRA               |
| AutoModelForCausalLM               | 文本生成（GPT 类）   | GPT-2, LLaMA, Mistral, Qwen |
| AutoModelForSeq2SeqLM              | 翻译、摘要（编解码器）   | T5, BART, mT5               |
| AutoModelForMaskedLM               | Fill-mask、预训练 | BERT, RoBERTa               |
| AutoModelForImageClassification    | 图像分类          | ViT, Swin Transformer       |

---

## Tokenizer 核心方法

### 编码与解码

```python
tokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-uncased")

# 编码：文本 → token id
encoding = tokenizer(
    "Hello, world!",
    add_special_tokens=True,   # 添加 [CLS] / [SEP] 等特殊 token
    max_length=128,
    padding="max_length",      # 填充到最大长度
    truncation=True,           # 超出截断
    return_attention_mask=True,
    return_tensors="pt",       # 返回 torch.Tensor
)
# encoding.input_ids, encoding.attention_mask, encoding.token_type_ids

# 批量编码（自动对齐 padding）
batch = tokenizer(
    ["sentence one", "sentence two"],
    padding=True,              # 同批次内对齐
    truncation=True,
    return_tensors="pt",
)

# 解码：token id → 文本
ids = [101, 7592, 1010, 2088, 999, 102]
text = tokenizer.decode(ids, skip_special_tokens=True)
# "hello , world !"

# 批量解码
texts = tokenizer.batch_decode(batch.input_ids, skip_special_tokens=True)

```

---

## 推理流程（手动）

```python
from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch

model_name = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name)
model.eval()

texts = ["I love this movie!", "This was a waste of time."]
inputs = tokenizer(texts, padding=True, truncation=True, return_tensors="pt")

with torch.no_grad():
    outputs = model(**inputs)

# outputs.logits: shape [batch_size, num_labels]
probs = torch.softmax(outputs.logits, dim=-1)
labels = model.config.id2label

for i, prob in enumerate(probs):
    pred = labels[prob.argmax().item()]
    print(f"{texts[i]!r}: {pred} ({prob.max():.4f})")

```

---

## 文本生成

```python
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

model_name = "microsoft/phi-2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16, device_map="auto")

inputs = tokenizer("Explain quantum computing in simple terms:", return_tensors="pt").to(model.device)

# generate() 核心参数
outputs = model.generate(
    **inputs,
    max_new_tokens=200,       # 最多新生成 200 个 token
    temperature=0.7,          # 采样温度；越高越随机，越低越确定
    top_p=0.9,                # nucleus sampling；累计概率阈值
    top_k=50,                 # top-k 采样
    do_sample=True,           # 开启采样（否则贪心解码）
    repetition_penalty=1.1,   # 惩罚重复 token
    pad_token_id=tokenizer.eos_token_id,
)

# 解码时只保留新生成的 token
new_tokens = outputs[0][inputs.input_ids.shape[1]:]
print(tokenizer.decode(new_tokens, skip_special_tokens=True))

```

### generate() 主要参数

| 参数                     | 类型          | 默认值   | 说明                                              |
| ---------------------- | ----------- | ----- | ----------------------------------------------- |
| max\_new\_tokens       | int         | None  | 最多生成的新 token 数（推荐用此参数替代 max\_length）            |
| max\_length            | int         | 20    | 输入 + 输出总 token 上限                               |
| do\_sample             | bool        | False | 是否采样；False 为贪心解码                                |
| temperature            | float       | 1.0   | 温度系数；< 1 更确定，\> 1 更随机                           |
| top\_p                 | float       | 1.0   | Nucleus sampling 阈值；0.9 表示从累计 90% 概率的 token 中采样 |
| top\_k                 | int         | 50    | Top-k 采样；每步只从概率最高的 k 个 token 中采样                |
| repetition\_penalty    | float       | 1.0   | 重复惩罚；\> 1 惩罚已出现的 token                          |
| num\_beams             | int         | 1     | Beam search 的束宽；1 关闭 beam search                |
| num\_return\_sequences | int         | 1     | 返回的候选序列数；需 num\_beams >= num\_return\_sequences |
| pad\_token\_id         | int         | None  | Padding token id；批量生成时必须设置                      |
| eos\_token\_id         | int \| list | None  | 结束 token id；遇到此 token 停止生成                      |

---

## Trainer — Fine-tuning 训练器

`Trainer` 封装了训练循环、梯度累积、混合精度、分布式训练等，是 Fine-tuning 的标准工具。

### TrainingArguments

```python
from transformers import TrainingArguments

args = TrainingArguments(
    output_dir="./results",              # 检查点保存路径
    num_train_epochs=3,
    per_device_train_batch_size=16,      # 每张 GPU 的批次大小
    per_device_eval_batch_size=64,
    warmup_steps=500,                    # 学习率预热步数
    weight_decay=0.01,                   # L2 正则化系数
    logging_dir="./logs",
    logging_steps=100,
    eval_strategy="epoch",              # 每个 epoch 评估一次
    save_strategy="epoch",
    load_best_model_at_end=True,         # 训练结束加载最优检查点
    fp16=True,                           # 开启混合精度（需要 CUDA）
    dataloader_num_workers=4,
    report_to="tensorboard",
)

```

| 参数                              | 类型          | 默认值     | 说明                                                                            |
| ------------------------------- | ----------- | ------- | ----------------------------------------------------------------------------- |
| output\_dir                     | str         | 必须      | 模型检查点和输出的保存路径                                                                 |
| num\_train\_epochs              | float       | 3.0     | 训练轮次                                                                          |
| per\_device\_train\_batch\_size | int         | 8       | 每张设备的训练批次大小                                                                   |
| per\_device\_eval\_batch\_size  | int         | 8       | 每张设备的评估批次大小                                                                   |
| learning\_rate                  | float       | 5e-5    | AdamW 优化器初始学习率                                                                |
| weight\_decay                   | float       | 0.0     | L2 正则化系数（AdamW 的权重衰减）                                                         |
| warmup\_steps                   | int         | 0       | 学习率线性预热步数                                                                     |
| warmup\_ratio                   | float       | 0.0     | 以训练总步数的比例设置预热（与 warmup\_steps 二选一）                                            |
| fp16                            | bool        | False   | 开启 FP16 混合精度训练（CUDA）                                                          |
| bf16                            | bool        | False   | 开启 BF16 混合精度训练（Ampere+ GPU）                                                   |
| gradient\_accumulation\_steps   | int         | 1       | 梯度累积步数；有效批次 = per\_device\_train\_batch\_size × gradient\_accumulation\_steps |
| eval\_strategy                  | str         | "no"    | 评估策略："no" / "steps" / "epoch"                                                 |
| save\_strategy                  | str         | "steps" | 保存策略："no" / "steps" / "epoch"                                                 |
| load\_best\_model\_at\_end      | bool        | False   | 训练结束时加载验证集最优检查点                                                               |
| report\_to                      | str \| list | "none"  | 实验追踪平台："tensorboard" / "wandb" / "none"                                       |
| dataloader\_num\_workers        | int         | 0       | DataLoader 工作进程数                                                              |

### Trainer 完整示例

```python
from transformers import (
    AutoTokenizer, AutoModelForSequenceClassification,
    TrainingArguments, Trainer
)
from datasets import load_dataset
import numpy as np
from sklearn.metrics import accuracy_score, f1_score

# 加载数据集
dataset = load_dataset("imdb")
tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")

def tokenize(examples):
    return tokenizer(examples["text"], truncation=True, max_length=512)

tokenized = dataset.map(tokenize, batched=True, remove_columns=["text"])
tokenized = tokenized.rename_column("label", "labels")

# 加载模型
model = AutoModelForSequenceClassification.from_pretrained(
    "distilbert-base-uncased", num_labels=2
)

# 定义评估指标
def compute_metrics(eval_pred):
    logits, labels = eval_pred
    preds = np.argmax(logits, axis=-1)
    return {
        "accuracy": accuracy_score(labels, preds),
        "f1": f1_score(labels, preds, average="weighted"),
    }

training_args = TrainingArguments(
    output_dir="./imdb-distilbert",
    num_train_epochs=3,
    per_device_train_batch_size=32,
    per_device_eval_batch_size=64,
    warmup_ratio=0.1,
    weight_decay=0.01,
    eval_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
    fp16=True,
    report_to="tensorboard",
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized["train"],
    eval_dataset=tokenized["test"],
    tokenizer=tokenizer,
    compute_metrics=compute_metrics,
)

trainer.train()
trainer.save_model("./best-imdb-distilbert")

```

---

## 模型保存与加载

```python
# 保存（本地）
model.save_pretrained("./my_model")
tokenizer.save_pretrained("./my_model")

# 加载本地
model = AutoModelForSequenceClassification.from_pretrained("./my_model")
tokenizer = AutoTokenizer.from_pretrained("./my_model")

# 推送到 Hub（需要登录）
# huggingface-cli login
model.push_to_hub("my-username/my-model-name")
tokenizer.push_to_hub("my-username/my-model-name")

```

---

## 最佳实践

**在生产环境中复用 pipeline 实例**：每次调用 `pipeline()` 都会重新加载模型权重，开销极大。应在应用启动时初始化一次，后续复用同一个实例。

```python
# 正确：全局单例
_clf = None
def get_classifier():
    global _clf
    if _clf is None:
        _clf = pipeline("text-classification", model="...", device=0)
    return _clf

# 错误：每次请求都重新创建
def classify(text):
    clf = pipeline("text-classification")  # 重新加载模型，极慢
    return clf(text)

```

**用 `torch.no_grad()` 和 `model.eval()` 推理**：不添加这两个上下文时，PyTorch 会构建计算图并保留梯度，推理时浪费约 30% 内存。

```python
model.eval()
with torch.no_grad():
    outputs = model(**inputs)

```

**量化大模型降低显存门槛**：70B 参数模型全精度需约 140GB 显存，4-bit 量化后约 35GB，可在单张 A100 80G 上运行。推理精度损失通常在 1–2% 以内。

```python
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-3.2-70B",
    load_in_4bit=True,
    device_map="auto",
    bnb_4bit_compute_dtype=torch.bfloat16,
)

```

**使用 `datasets` 库处理大规模数据集**：`datasets` 支持内存映射（Arrow 格式），100GB 数据集无需全量载入内存，配合 `.map(batched=True)` 并行处理可显著加速预处理。

```python
from datasets import load_dataset

dataset = load_dataset("json", data_files="data.jsonl", split="train")
tokenized = dataset.map(
    lambda x: tokenizer(x["text"], truncation=True),
    batched=True,
    num_proc=4,           # 4 进程并行
    remove_columns=["text"],
)

```

**通过 `revision` 锁定模型版本**：Hub 上的模型权重可能随时更新，生产环境应固定到特定 commit id，避免模型漂移。

```python
model = AutoModel.from_pretrained(
    "google-bert/bert-base-uncased",
    revision="7f56ae30",   # 锁定到具体 commit
)

```

**批量推理优于逐条推理**：逐条调用 pipeline 时 GPU 利用率通常不足 10%，传入列表可以触发批量矩阵乘法，吞吐量提升 5–20 倍。

```python
# 正确：批量传入
results = clf(["text1", "text2", "text3", ..., "text64"])

# 低效：逐条处理
results = [clf(text) for text in texts]

```

---

## 常见陷阱

### 陷阱：设备不一致导致 RuntimeError

**现象：** `RuntimeError: Expected all tensors to be on the same device`

**原因：** 模型在 GPU，但 input tensor 在 CPU；或者反过来。

**解决：** 调用 `.to(model.device)` 将输入移到与模型相同的设备。

```python
model = model.to("cuda")
inputs = tokenizer(text, return_tensors="pt")
inputs = {k: v.to(model.device) for k, v in inputs.items()}  # 正确
# inputs = inputs.to("cuda")  # 错误：dict 没有 .to() 方法

```

---

### 陷阱：生成时不设置 pad\_token\_id

**现象：** 批量调用 `generate()` 时警告 `Setting pad_token_id to eos_token_id`，结果截断或质量下降。

**原因：** GPT 类模型（LLaMA、Mistral 等）没有 `pad_token` 设计，批量生成时长度不一致需要 padding。

**解决：** 显式设置 `pad_token_id`，并将 tokenizer 的 padding 方向改为左侧。

```python
tokenizer.padding_side = "left"   # 生成任务用左侧 padding
outputs = model.generate(
    **inputs,
    pad_token_id=tokenizer.eos_token_id,
    max_new_tokens=100,
)

```

---

### 陷阱：Fine-tuning 时忘记 num\_labels

**现象：** 训练文本分类时 loss 异常高，模型不收敛。

**原因：** `from_pretrained` 时若不指定 `num_labels`，分类头的输出维度默认为 2（二分类），多分类任务下计算 loss 时维度不匹配。

**解决：** 加载模型时传入正确的 `num_labels`。

```python
# 错误：5 分类任务用默认 num_labels=2
model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased")

# 正确：明确指定类别数
model = AutoModelForSequenceClassification.from_pretrained(
    "bert-base-uncased",
    num_labels=5,
    id2label={0: "1-star", 1: "2-star", 2: "3-star", 3: "4-star", 4: "5-star"},
    label2id={"1-star": 0, "2-star": 1, "3-star": 2, "4-star": 3, "5-star": 4},
)

```

---

### 陷阱：在训练循环中保留计算图耗尽内存

**现象：** 训练过程中 GPU 内存持续增长，最终 OOM。

**原因：** `loss.item()` 之前调用了 `loss.detach()` 或在日志记录时直接存储 loss tensor，导致整个计算图被保留在内存中。

**解决：** 使用 `.item()` 将标量提取为 Python float，释放计算图。

```python
# 错误：保留了 tensor（及其完整计算图）
train_losses.append(loss)

# 正确：提取 Python float
train_losses.append(loss.item())

```

---

## 参见

- [scikit-learn完全指南](https://blog.vercanti.com/scikit-learn-wan-quan-zhi-nan/)
- [LangChain完全指南](https://blog.vercanti.com/langchain-wan-quan-zhi-nan/)
- [PyTorch完全指南](https://blog.vercanti.com/pytorchwan-quan-zhi-nan/)