Skip to content

Hugging Face NLP Course 第 3-5 模块中英对照

课程: Hugging Face NLP Course
原链接: https://huggingface.co/learn/nlp-course
版本: transformers >= 4.40.0
翻译时间: 2026-06-01
状态: 中英对照编译版
前续: 第 1 模块, 第 2 模块


📚 目录 (Table of Contents)

Module 3: Fine-tuning for Specific Tasks

模块 3: 特定任务的微调

  • Chapter 3/1: Fine-tuning for Text Classification (文本分类微调)
  • Chapter 3/2: Fine-tuning for Question Answering (问答微调)
  • Chapter 3/3: Fine-tuning for Named Entity Recognition (命名实体识别微调)

Module 4: Building and Sharing Models

模块 4: 构建和共享模型

  • Chapter 4/1: The Hugging Face Hub (Hugging Face Hub)
  • Chapter 4/2: Sharing Models and Datasets (共享模型和数据集)
  • Chapter 4/3: Creating Model Cards (创建模型卡片)

Module 5: Deployment and Production

模块 5: 部署和生产

  • Chapter 5/1: Model Optimization (模型优化)
  • Chapter 5/2: Deployment with Inference APIs (使用推理 API 部署)
  • Chapter 5/3: Production Best Practices (生产最佳实践)

Module 3: Fine-tuning for Specific Tasks

模块 3: 特定任务的微调

Chapter 3/1: Fine-tuning for Text Classification

第 3/1 章:文本分类微调

English:

Text classification is one of the most common NLP tasks. It involves assigning a label or category to a given text. Examples include sentiment analysis, topic classification, and spam detection.

中文:

文本分类是最常见的 NLP 任务之一。它涉及为给定文本分配标签或类别。示例包括情感分析、主题分类和垃圾邮件检测。

完整微调示例 (Complete Fine-tuning Example):

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

# 1. 加载数据集
dataset = load_dataset("imdb")

# 2. 加载预训练模型和 tokenizer
model_name = "distilbert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(
    model_name,
    num_labels=2,  # 二分类:正面/负面
    id2label={0: "NEGATIVE", 1: "POSITIVE"},
    label2id={"NEGATIVE": 0, "POSITIVE": 1}
)

# 3. 预处理数据
def tokenize_function(examples):
    return tokenizer(
        examples["text"],
        padding="max_length",
        truncation=True,
        max_length=512
    )

tokenized_datasets = dataset.map(
    tokenize_function,
    batched=True,
    remove_columns=["text"]
)

# 4. 数据整理器
from transformers import DataCollatorWithPadding
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

# 5. 评估指标
def compute_metrics(eval_pred):
    logits, labels = eval_pred
    predictions = np.argmax(logits, axis=-1)
    return {
        "accuracy": accuracy_score(labels, predictions),
        "f1_macro": f1_score(labels, predictions, average="macro"),
        "f1_weighted": f1_score(labels, predictions, average="weighted")
    }

# 6. 训练参数
training_args = TrainingArguments(
    output_dir="./text-classification",
    learning_rate=2e-5,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=64,
    num_train_epochs=3,
    weight_decay=0.01,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
    logging_steps=100,
    push_to_hub=False,  # 设置为 True 可上传到 Hub
)

# 7. 创建 Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["test"],
    tokenizer=tokenizer,
    data_collator=data_collator,
    compute_metrics=compute_metrics,
)

# 8. 开始训练
trainer.train()

# 9. 评估
results = trainer.evaluate()
print(f"Evaluation results: {results}")

# 10. 保存模型
trainer.save_model("./text-classification-model")

Chapter 3/2: Fine-tuning for Question Answering

第 3/2 章:问答微调

English:

Question answering (QA) models take a question and a context, and return the answer as a span of text from the context.

中文:

问答 (QA) 模型接受问题和上下文,返回上下文中文本片段作为答案。

SQuAD 数据集微调示例 (SQuAD Fine-tuning Example):

from datasets import load_dataset
from transformers import AutoTokenizer, AutoModelForQuestionAnswering
from transformers import TrainingArguments, Trainer
import collections

# 1. 加载 SQuAD 数据集
datasets = load_dataset("squad")

# 2. 加载模型和 tokenizer
model_name = "distilbert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForQuestionAnswering.from_pretrained(model_name)

# 3. 预处理函数
max_length = 384
doc_stride = 128

def preprocess_function(examples):
    # 截断过长的问题
    questions = [q.strip() for q in examples["question"]]

    # Tokenize
    inputs = tokenizer(
        questions,
        examples["context"],
        max_length=max_length,
        truncation="only_second",
        return_overflowing_tokens=True,
        stride=doc_stride,
        return_offsets_mapping=True,
        padding="max_length",
    )

    # 映射答案
    offset_mapping = inputs.pop("offset_mapping")
    sample_map = inputs.pop("overflow_to_sample_mapping")

    start_positions = []
    end_positions = []

    for i, offsets in enumerate(offset_mapping):
        input_ids = inputs["input_ids"][i]
        cls_index = input_ids.index(tokenizer.cls_token_id)

        # 获取样本信息
        sequence_ids = inputs.sequence_ids(i)
        sample_index = sample_map[i]
        answers = examples["answers"][sample_index]

        # 如果没有答案
        if len(answers["answer_start"]) == 0:
            start_positions.append(cls_index)
            end_positions.append(cls_index)
        else:
            start_char = answers["answer_start"][0]
            end_char = answers["answer_start"][0] + len(answers["text"][0])

            # 找到 token 范围
            token_start_index = 0
            while sequence_ids[token_start_index] != 1:
                token_start_index += 1

            token_end_index = len(input_ids) - 1
            while sequence_ids[token_end_index] != 1:
                token_end_index -= 1

            # 检查答案是否在上下文中
            if not (offsets[token_start_index][0] <= start_char and 
                    offsets[token_end_index][1] >= end_char):
                start_positions.append(cls_index)
                end_positions.append(cls_index)
            else:
                while token_start_index < len(offsets) and \
                      offsets[token_start_index][0] <= start_char:
                    token_start_index += 1
                start_positions.append(token_start_index - 1)

                while offsets[token_end_index][1] >= end_char:
                    token_end_index -= 1
                end_positions.append(token_end_index + 1)

    inputs["start_positions"] = start_positions
    inputs["end_positions"] = end_positions
    return inputs

# 4. 处理数据集
tokenized_datasets = datasets.map(
    preprocess_function,
    batched=True,
    remove_columns=datasets["train"].column_names
)

# 5. 训练参数
training_args = TrainingArguments(
    output_dir="./question-answering",
    learning_rate=3e-5,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=64,
    num_train_epochs=3,
    weight_decay=0.01,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
)

# 6. 创建 Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    tokenizer=tokenizer,
)

# 7. 训练
trainer.train()

# 8. 保存
trainer.save_model("./qa-model")

使用微调后的 QA 模型 (Using Fine-tuned QA Model):

from transformers import pipeline

# 加载微调后的模型
qa_pipeline = pipeline(
    "question-answering",
    model="./qa-model",
    tokenizer="./qa-model"
)

# 使用示例
context = """
Hugging Face is a technology company that builds natural language processing tools.
It is known for its Transformers library which provides pre-trained models for various NLP tasks.
The company was founded in 2016 and is based in New York.
"""

question = "When was Hugging Face founded?"
result = qa_pipeline(question=question, context=context)

print(f"Answer: {result['answer']}")
print(f"Confidence: {result['score']:.2f}")
# 输出:Answer: 2016
#      Confidence: 0.95

Chapter 3/3: Fine-tuning for Named Entity Recognition

第 3/3 章:命名实体识别微调

English:

Named Entity Recognition (NER) is the task of identifying and classifying named entities in text into predefined categories such as person, organization, location, etc.

中文:

命名实体识别 (NER) 是识别文本中的命名实体并将其分类为预定义类别(如人物、组织、地点等)的任务。

NER 微调完整示例 (Complete NER Fine-tuning Example):

from datasets import load_dataset
from transformers import AutoTokenizer, AutoModelForTokenClassification
from transformers import TrainingArguments, Trainer
import numpy as np
from seqeval.metrics import accuracy_score, f1_score

# 1. 加载数据集 (ConLL 2003)
dataset = load_dataset("conll2003")

# 2. 标签映射
label_list = dataset["train"].features["ner_tags"].feature.names
print(f"Labels: {label_list}")
# ['O', 'B-PER', 'I-PER', 'B-ORG', 'I-ORG', 'B-LOC', 'I-LOC', 'B-MISC', 'I-MISC']

# 3. 加载模型和 tokenizer
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForTokenClassification.from_pretrained(
    model_name,
    num_labels=len(label_list),
    id2label={i: label for i, label in enumerate(label_list)},
    label2id={label: i for i, label in enumerate(label_list)}
)

# 4. 预处理函数
def tokenize_and_align_labels(examples):
    tokenized_inputs = tokenizer(
        examples["tokens"],
        is_split_into_words=True,
        padding="max_length",
        truncation=True,
        max_length=128
    )

    labels = []
    for i, label in enumerate(examples["ner_tags"]):
        word_ids = tokenized_inputs.word_ids(batch_index=i)
        previous_word_idx = None
        label_ids = []

        for word_idx in word_ids:
            if word_idx is None:
                label_ids.append(-100)  # 特殊 token 的标签设为 -100
            elif word_idx != previous_word_idx:
                label_ids.append(label[word_idx])
            else:
                label_ids.append(-100)  # 同一词的后续 token 设为 -100
            previous_word_idx = word_idx

        labels.append(label_ids)

    tokenized_inputs["labels"] = labels
    return tokenized_inputs

# 5. 处理数据集
tokenized_datasets = dataset.map(
    tokenize_and_align_labels,
    batched=True,
    remove_columns=dataset["train"].column_names
)

# 6. 数据整理器
from transformers import DataCollatorForTokenClassification
data_collator = DataCollatorForTokenClassification(tokenizer)

# 7. 评估指标
def compute_metrics(eval_pred):
    logits, labels = eval_pred
    predictions = np.argmax(logits, axis=-1)

    # 移除 -100 标签
    true_predictions = [
        [label_list[p] for (p, l) in zip(prediction, label) if l != -100]
        for prediction, label in zip(predictions, labels)
    ]
    true_labels = [
        [label_list[l] for (p, l) in zip(prediction, label) if l != -100]
        for prediction, label in zip(predictions, labels)
    ]

    return {
        "accuracy": accuracy_score(true_labels, true_predictions),
        "f1": f1_score(true_labels, true_predictions),
    }

# 8. 训练参数
training_args = TrainingArguments(
    output_dir="./ner-model",
    learning_rate=2e-5,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=64,
    num_train_epochs=5,
    weight_decay=0.01,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
)

# 9. 创建 Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    tokenizer=tokenizer,
    data_collator=data_collator,
    compute_metrics=compute_metrics,
)

# 10. 训练
trainer.train()

# 11. 保存
trainer.save_model("./ner-model")

使用 NER 模型 (Using NER Model):

from transformers import pipeline

# 加载 NER 模型
ner_pipeline = pipeline(
    "token-classification",
    model="./ner-model",
    aggregation_strategy="simple"  # 聚合子词为完整实体
)

# 使用示例
text = """
Apple Inc. is headquartered in Cupertino, California.
Tim Cook is the CEO of Apple.
"""

entities = ner_pipeline(text)

for entity in entities:
    print(f"{entity['entity_group']}: {entity['word']} "
          f"(confidence: {entity['score']:.2f})")

# 输出:
# ORG: Apple Inc. (confidence: 0.99)
# LOC: Cupertino (confidence: 0.95)
# LOC: California (confidence: 0.96)
# PER: Tim Cook (confidence: 0.98)
# ORG: Apple (confidence: 0.97)

Module 4: Building and Sharing Models

模块 4: 构建和共享模型

Chapter 4/1: The Hugging Face Hub

第 4/1 章:Hugging Face Hub

English:

The Hugging Face Hub is a platform for sharing and discovering machine learning models, datasets, and demos. It hosts over 500,000 models and 100,000 datasets.

中文:

Hugging Face Hub 是一个共享和发现机器学习模型、数据集和演示的平台。它托管了超过 500,000 个模型和 100,000 个数据集。

Hub 功能 (Hub Features):

功能 英文 中文 说明
Models Models 模型 预训练和微调模型
Datasets Datasets 数据集 训练和评估数据
Spaces Spaces 空间 交互式演示应用
Organizations Organizations 组织 团队协作空间
Discussions Discussions 讨论 模型卡片评论

上传模型到 Hub (Uploading Models to Hub):

from huggingface_hub import HfApi, login

# 1. 登录(使用 API token)
login(token="your_hf_token")

# 2. 创建仓库
api = HfApi()
api.create_repo(
    repo_id="my-awesome-model",
    repo_type="model",
    exist_ok=True
)

# 3. 上传模型
api.upload_folder(
    folder_path="./text-classification-model",
    repo_id="my-awesome-model",
    repo_type="model"
)

print("Model uploaded successfully!")

使用 Trainer 直接上传 (Direct Upload with Trainer):

# 在 TrainingArguments 中设置 push_to_hub=True
training_args = TrainingArguments(
    output_dir="./model",
    push_to_hub=True,  # 训练完成后自动上传
    hub_model_id="my-username/my-awesome-model",
    hub_strategy="every_save",  # 每次保存都上传
    # ... 其他参数
)

# 训练后自动上传
trainer.train()
trainer.push_to_hub()  # 或手动推送

Chapter 4/2: Sharing Models and Datasets

第 4/2 章:共享模型和数据集

English:

Sharing your models and datasets on the Hub enables collaboration and reproducibility. It also allows others to build upon your work.

中文:

在 Hub 上共享你的模型和数据集可以促进协作和可重复性。它还允许他人在你的工作基础上构建。

创建模型卡片 (Creating a Model Card):

---
language:
- en
- zh
tags:
- text-classification
- sentiment-analysis
- distilbert
license: mit
datasets:
- imdb
metrics:
- accuracy
- f1
---

# Model Card for My Sentiment Analysis Model

## Model Description

This is a fine-tuned DistilBERT model for sentiment analysis on movie reviews.

## Training Data

- Dataset: IMDb Movie Reviews
- Size: 50,000 reviews
- Languages: English

## Training Procedure

- Base model: distilbert-base-uncased
- Epochs: 3
- Batch size: 16
- Learning rate: 2e-5

## Evaluation Results

| Metric | Value |
|--------|-------|
| Accuracy | 0.91 |
| F1 (macro) | 0.91 |

## How to Use

```python
from transformers import pipeline

classifier = pipeline("sentiment-analysis", 
                     model="username/my-awesome-model")
result = classifier("I love this movie!")

Limitations

  • Only trained on English movie reviews
  • May not generalize well to other domains
    **共享数据集 (Sharing Datasets)**:
    
    ```python
    from datasets import Dataset
    from huggingface_hub import HfApi
    
    # 1. 准备数据集
    data = {
        "text": ["Great product!", "Terrible service."],
        "label": [1, 0]
    }
    dataset = Dataset.from_dict(data)
    
    # 2. 推送到 Hub
    dataset.push_to_hub("my-username/my-dataset")
    
    # 3. 其他人可以加载
    from datasets import load_dataset
    loaded_dataset = load_dataset("my-username/my-dataset")
    

Chapter 4/3: Creating Model Cards

第 4/3 章:创建模型卡片

English:

Model cards provide documentation for machine learning models. They should include information about the model's intended use, training data, evaluation results, and limitations.

中文:

模型卡片为机器学习模型提供文档。它们应包括有关模型的预期用途、训练数据、评估结果和局限性的信息。

模型卡片必备要素 (Essential Model Card Elements):

部分 英文 中文 重要性
Model Details Model Details 模型详情 ⭐⭐⭐⭐⭐
Intended Use Intended Use 预期用途 ⭐⭐⭐⭐⭐
Training Data Training Data 训练数据 ⭐⭐⭐⭐⭐
Evaluation Evaluation 评估结果 ⭐⭐⭐⭐⭐
Limitations Limitations 局限性 ⭐⭐⭐⭐
Ethical Considerations Ethical Considerations 伦理考虑 ⭐⭐⭐⭐
Citation Citation 引用 ⭐⭐⭐

Module 5: Deployment and Production

模块 5: 部署和生产

Chapter 5/1: Model Optimization

第 5/1 章:模型优化

English:

Model optimization techniques reduce model size and improve inference speed, making deployment more efficient.

中文:

模型优化技术减少模型大小并提高推理速度,使部署更高效。

优化技术对比 (Optimization Techniques Comparison):

技术 英文 压缩比 速度提升 精度损失
量化 Quantization 4x 2-3x <1%
剪枝 Pruning 2-3x 1.5-2x 1-3%
知识蒸馏 Knowledge Distillation 5-10x 3-5x 2-5%
ONNX ONNX 1-2x 2-3x <1%

动态量化 (Dynamic Quantization):

from transformers import AutoModelForSequenceClassification
import torch

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

# 动态量化
quantized_model = torch.quantization.quantize_dynamic(
    model,
    {torch.nn.Linear},
    dtype=torch.qint8
)

# 保存量化模型
torch.save(quantized_model.state_dict(), "quantized_model.pt")

# 检查大小
import os
original_size = os.path.getsize("original_model.pt")
quantized_size = os.path.getsize("quantized_model.pt")

print(f"Original: {original_size / 1e6:.2f} MB")
print(f"Quantized: {quantized_size / 1e6:.2f} MB")
print(f"Compression: {original_size / quantized_size:.2f}x")

ONNX 导出 (ONNX Export):

from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch

# 加载模型
model_name = "distilbert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name)
model.eval()

# 创建示例输入
dummy_input = tokenizer(
    "Example input for ONNX export",
    return_tensors="pt",
    padding="max_length",
    max_length=128
)

# 导出为 ONNX
torch.onnx.export(
    model,
    (dummy_input["input_ids"], dummy_input["attention_mask"]),
    "model.onnx",
    opset_version=11,
    input_names=["input_ids", "attention_mask"],
    output_names=["logits"],
    dynamic_axes={
        "input_ids": {0: "batch_size", 1: "sequence_length"},
        "attention_mask": {0: "batch_size", 1: "sequence_length"},
        "logits": {0: "batch_size"}
    }
)

print("Model exported to ONNX format!")

Chapter 5/2: Deployment with Inference APIs

第 5/2 章:使用推理 API 部署

English:

Hugging Face Inference API provides a simple way to deploy and serve models without managing infrastructure.

中文:

Hugging Face 推理 API 提供了一种简单的方法来部署和服务模型,而无需管理基础设施。

使用 Inference API (Using Inference API):

from huggingface_hub import InferenceClient

# 1. 创建客户端
client = InferenceClient(token="your_hf_token")

# 2. 文本分类
result = client.text_classification(
    "I love using Hugging Face!",
    model="distilbert-base-uncased-finetuned-sst-2-english"
)
print(result)

# 3. 问答
result = client.question_answering(
    question="What is NLP?",
    context="NLP stands for Natural Language Processing.",
    model="deepset/roberta-base-squad2"
)
print(result)

# 4. 文本生成
result = client.text_generation(
    "Once upon a time",
    model="gpt2",
    max_new_tokens=50
)
print(result)

部署自定义模型 (Deploying Custom Models):

# 在模型仓库中添加 inference-api 配置
# config.json 中添加:
{
  "architectures": ["AutoModelForSequenceClassification"],
  "custom_headers": {},
  "custom_parameters": {}
}

Chapter 5/3: Production Best Practices

第 5/3 章:生产最佳实践

English:

Deploying models to production requires careful consideration of performance, monitoring, and maintenance.

中文:

将模型部署到生产环境需要仔细考虑性能、监控和维护。

生产部署检查清单 (Production Deployment Checklist):

方面 检查项 重要性
性能 延迟 < 100ms ⭐⭐⭐⭐⭐
性能 吞吐量 > 100 QPS ⭐⭐⭐⭐
性能 模型量化/优化 ⭐⭐⭐⭐
监控 日志记录 ⭐⭐⭐⭐⭐
监控 指标收集 ⭐⭐⭐⭐⭐
监控 异常检测 ⭐⭐⭐⭐
安全 访问控制 ⭐⭐⭐⭐⭐
安全 输入验证 ⭐⭐⭐⭐⭐
维护 版本控制 ⭐⭐⭐⭐⭐
维护 A/B 测试能力 ⭐⭐⭐⭐
维护 回滚机制 ⭐⭐⭐⭐⭐

监控示例 (Monitoring Example):

import time
import logging
from prometheus_client import Counter, Histogram, start_http_server

# 定义指标
REQUEST_COUNT = Counter('model_requests_total', 'Total requests')
REQUEST_LATENCY = Histogram('model_request_latency_seconds', 'Request latency')
ERROR_COUNT = Counter('model_errors_total', 'Total errors')

# 设置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class MonitoredPipeline:
    def __init__(self, pipeline):
        self.pipeline = pipeline

    def __call__(self, input_data):
        start_time = time.time()
        REQUEST_COUNT.inc()

        try:
            result = self.pipeline(input_data)
            latency = time.time() - start_time
            REQUEST_LATENCY.observe(latency)
            logger.info(f"Request processed in {latency:.3f}s")
            return result
        except Exception as e:
            ERROR_COUNT.inc()
            logger.error(f"Error processing request: {e}")
            raise

# 启动监控服务器
start_http_server(8000)
print("Monitoring server started on port 8000")

🛠️ 实践练习 (Hands-on Exercises)

练习 1: 完整微调流程 (Exercise 1: Complete Fine-tuning Pipeline)

# TODO: 完成以下任务
# 1. 选择一个 Hugging Face 数据集
# 2. 选择一个预训练模型
# 3. 微调模型完成特定任务
# 4. 评估模型性能
# 5. 将模型上传到 Hub

from datasets import load_dataset
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from transformers import TrainingArguments, Trainer

# 你的代码在这里

练习 2: 模型优化 (Exercise 2: Model Optimization)

# TODO: 对微调后的模型进行优化
# 1. 应用动态量化
# 2. 导出为 ONNX 格式
# 3. 比较优化前后的大小和推理速度

import torch
import time

# 你的代码在这里

练习 3: 创建模型卡片 (Exercise 3: Create a Model Card)

# TODO: 为你的模型创建完整的模型卡片
# 包括:模型描述、训练数据、评估结果、局限性、使用示例

---
language:
- <your-languages>
tags:
- <your-tags>
license: <your-license>
---

# Model Card for <Your Model Name>
...

翻译完成时间: 2026-06-01
原课程模块: Module 3-5
前续: 第 1 模块, 第 2 模块
后续: 高级主题 (待创建)


**Hugging Face NLP Course 中英对照 | 第 3-5 模块** [返回顶部](#目录-table-of-contents)