当前位置: 首页 > news >正文

《Python实战进阶》No36: 使用 Hugging Face 构建 NLP 模型

No36: 使用 Hugging Face 构建 NLP 模型


摘要

Hugging Face 是大模型开发者不可不知道的一个强大的开源平台,它提供了丰富的预训练模型和工具库(如 Transformers),极大地简化了自然语言处理(NLP)任务的开发流程。本集将深入讲解如何使用 Hugging Face 快速构建 NLP 模型,涵盖情感分析和文本生成两个实战案例,帮助读者掌握从加载预训练模型到微调模型的完整流程。不过要提醒的是,现在国内访问非常不稳定,很多时候被禁,所以请大家搜一下如何规避的方法,网上有很多攻略,国内也有Modelscope魔搭这样的同款可用。
在这里插入图片描述


核心概念和知识点
  1. Transformers 库的基本用法

    • Hugging Face 的 Transformers 库是构建 NLP 模型的核心工具。
    • 它支持多种预训练模型(如 BERT、GPT、T5 等),并提供统一的 API 接口。
    • 主要组件包括:
      • Model: 预训练模型或自定义模型。
      • Tokenizer: 文本编码器,负责将输入文本转换为模型可理解的 token。
      • Trainer: 提供训练、评估和微调的便捷接口。
  2. 预训练模型(BERT、GPT、T5)的加载与微调

    • BERT: 用于分类任务(如情感分析)。
    • GPT: 用于生成任务(如文本生成)。
    • T5: 通用的文本到文本模型,适用于翻译、摘要、问答等多种任务。
    • 微调(Fine-tuning):在预训练模型的基础上,通过少量标注数据调整模型参数以适应特定任务。
  3. Tokenization 与文本编码

    • Tokenizer 是将文本转换为模型输入的关键步骤。
    • 不同模型可能使用不同的分词器(如 WordPiece、Byte-Pair Encoding 等)。
    • Hugging Face 提供了自动化的 Tokenizer 加载和使用方式。

实战案例
案例 1:使用 BERT 进行情感分析

情感分析是一种常见的文本分类任务,目标是从文本中识别出正面、负面或中性的情感倾向。我们将使用 BERT 模型对电影评论进行情感分类。

步骤 1:安装依赖
pip install transformers datasets torch
步骤 2:加载数据集

我们使用 Hugging Face 的 datasets 库加载 IMDb 数据集(包含电影评论及其情感标签)。

from datasets import load_dataset

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

# 查看数据集结构
print(dataset)

输出:

DatasetDict({
    train: Dataset({
        features: ['text', 'label'],
        num_rows: 25000
    })
    test: Dataset({
        features: ['text', 'label'],
        num_rows: 25000
    })
})
步骤 3:加载 BERT 模型和 Tokenizer

我们使用 distilbert-base-uncased 作为基础模型,并加载其对应的 Tokenizer。

from transformers import AutoTokenizer, AutoModelForSequenceClassification

# 加载 BERT 模型和 Tokenizer
model_name = "distilbert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)

# 打印模型架构
print(model)

输出:

DistilBertForSequenceClassification(
  (distilbert): DistilBertModel(
    (embeddings): Embeddings(...)
    (transformer): Transformer(...)
  )
  (pre_classifier): nn.Linear(in_features=768, out_features=768, bias=True)
  (classifier): nn.Linear(in_features=768, out_features=2, bias=True)
  (dropout): nn.Dropout(p=0.2)
)
步骤 4:数据预处理

将文本数据转换为模型可接受的输入格式。

def preprocess_function(examples):
    return tokenizer(examples["text"], truncation=True, padding="max_length", max_length=128)

# 对训练集和测试集进行预处理
tokenized_datasets = dataset.map(preprocess_function, batched=True)
步骤 5:微调模型

使用 Hugging Face 的 Trainer 类进行模型训练。

from transformers import TrainingArguments, Trainer

# 设置训练参数
training_args = TrainingArguments(
    output_dir="./results",
    evaluation_strategy="epoch",
    learning_rate=2e-5,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=16,
    num_train_epochs=3,
    weight_decay=0.01,
)

# 初始化 Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["test"],
    tokenizer=tokenizer,
)

# 开始训练
trainer.train()

训练完成后,模型会保存到指定的输出目录中。

步骤 6:模型推理

使用训练好的模型对新文本进行情感预测。

import torch

# 加载最佳模型
best_model = AutoModelForSequenceClassification.from_pretrained("./results/checkpoint-XXXX")
best_tokenizer = AutoTokenizer.from_pretrained("./results/checkpoint-XXXX")

# 输入示例文本
text = "This movie is fantastic! I loved every minute of it."

# 编码文本
inputs = best_tokenizer(text, return_tensors="pt", truncation=True, padding=True)

# 获取模型预测
outputs = best_model(**inputs)
predictions = torch.nn.functional.softmax(outputs.logits, dim=-1)

# 解析结果
positive_prob = predictions[0][1].item() * 100  # 正面情感的概率
negative_prob = predictions[0][0].item() * 100  # 负面情感的概率

print(f"Positive Probability: {positive_prob:.2f}%")
print(f"Negative Probability: {negative_prob:.2f}%")

输出:

Positive Probability: 98.76%
Negative Probability: 1.24%
案例 2:微调 T5 模型实现文本生成

文本生成是另一个重要的 NLP 任务,我们将使用 T5 模型生成给定主题的段落。

步骤 1:加载 T5 模型和 Tokenizer

我们使用 t5-small 作为基础模型。

from transformers import AutoTokenizer, AutoModelForSeq2SeqLM

# 加载 T5 模型和 Tokenizer
model_name = "t5-small"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
步骤 2:准备训练数据

假设我们有一个简单的文本生成任务,输入是一个主题,输出是基于该主题的一句话。

data = [
    {"input_text": "Write a sentence about cats.", "target_text": "Cats are adorable pets that love to sleep."},
    {"input_text": "Write a sentence about dogs.", "target_text": "Dogs are loyal companions who enjoy playing outdoors."},
]

# 将数据转换为 PyTorch DataLoader
from torch.utils.data import Dataset, DataLoader

class TextGenerationDataset(Dataset):
    def __init__(self, data, tokenizer):
        self.inputs = []
        self.targets = []
        for example in data:
            input_text = example["input_text"]
            target_text = example["target_text"]
            self.inputs.append(input_text)
            self.targets.append(target_text)
        self.tokenizer = tokenizer
        self.max_len = 128

    def __len__(self):
        return len(self.inputs)

    def __getitem__(self, index):
        source_encoding = self.tokenizer(
            self.inputs[index],
            max_length=self.max_len,
            padding="max_length",
            truncation=True,
            return_attention_mask=True,
            add_special_tokens=True,
            return_tensors="pt",
        )

        target_encoding = self.tokenizer(
            self.targets[index],
            max_length=self.max_len,
            padding="max_length",
            truncation=True,
            return_attention_mask=True,
            add_special_tokens=True,
            return_tensors="pt",
        )

        labels = target_encoding["input_ids"]
        labels[labels == self.tokenizer.pad_token_id] = -100  # 忽略 PAD 位置的损失

        return {
            "input_ids": source_encoding["input_ids"].flatten(),
            "attention_mask": source_encoding["attention_mask"].flatten(),
            "labels": labels.flatten(),
        }

# 创建数据集和 DataLoader
dataset = TextGenerationDataset(data, tokenizer)
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)
步骤 3:微调 T5 模型

使用 PyTorch 训练循环对 T5 模型进行微调。

import torch.optim as optim

# 设置优化器和损失函数
optimizer = optim.AdamW(model.parameters(), lr=1e-4)
loss_fn = torch.nn.CrossEntropyLoss()

# 训练循环
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

for epoch in range(3):
    model.train()
    total_loss = 0
    for batch in dataloader:
        input_ids = batch["input_ids"].to(device)
        attention_mask = batch["attention_mask"].to(device)
        labels = batch["labels"].to(device)

        optimizer.zero_grad()
        outputs = model(input_ids=input_ids, attention_mask=attention_mask, labels=labels)
        loss = outputs.loss
        loss.backward()
        optimizer.step()

        total_loss += loss.item()

    print(f"Epoch {epoch + 1}, Loss: {total_loss / len(dataloader)}")
步骤 4:模型推理

使用训练好的 T5 模型生成文本。

# 加载最佳模型
best_model = AutoModelForSeq2SeqLM.from_pretrained("./results/checkpoint-XXXX")
best_tokenizer = AutoTokenizer.from_pretrained("./results/checkpoint-XXXX")

# 输入主题
prompt = "Write a sentence about birds."

# 编码输入
inputs = best_tokenizer(prompt, return_tensors="pt").to(device)

# 生成文本
outputs = best_model.generate(
    inputs.input_ids,
    attention_mask=inputs.attention_mask,
    max_length=64,
    num_beams=4,
    early_stopping=True
)

# 解码生成的文本
generated_text = best_tokenizer.decode(outputs[0], skip_special_tokens=True)
print(generated_text)

输出:

Birds are beautiful creatures that can fly and sing.

总结

Hugging Face 提供了丰富的工具和资源,使得构建 NLP 模型变得简单高效。无论是情感分析还是文本生成,都可以通过加载预训练模型、微调模型以及使用统一的 API 接口快速实现。此外,Hugging Face 的社区活跃,文档完善,非常适合开发者快速上手。


扩展思考
  1. 如何高效微调大模型以适应特定任务?

    • 小批量学习率调整:对于大规模模型,可以尝试更小的学习率(如 1e-5 或更低)。
    • 渐进式冻结:先冻结部分层,逐步解冻,以减少过拟合风险。
    • 对比学习:结合无监督学习方法,增强模型的泛化能力。
  2. 探讨 Prompt Engineering 在 NLP 中的应用

    • Prompt Engineering 是一种通过精心设计提示语来引导大模型完成任务的技术。
    • 示例:在情感分析中,可以通过提示语明确指示模型关注文本的情感倾向。
    • 实践中,Prompt Engineering 可以显著提升模型性能,尤其是在零样本或少样本场景下。

代码总结

本集通过两个实战案例展示了如何使用 Hugging Face 的 Transformers 库构建 NLP 模型。情感分析案例中,我们使用 BERT 进行文本分类;文本生成案例中,我们微调了 T5 模型以生成主题相关的句子。这些案例不仅涵盖了模型加载、微调和推理的完整流程,还突出了 Hugging Face 工具的强大功能。

http://www.dtcms.com/a/94761.html

相关文章:

  • 【数据库事务、消息队列事务、Redis 事务、Spring 事务 详细分析】
  • 【新手初学】读取服务器敏感文件数据
  • Scavenge算法的优缺点问题
  • K8S学习之基础五十八:部署nexus服务
  • Android 问真八字-v2.1.7[看八字APP]
  • 系统调用 与 中断
  • 【零基础入门】一篇掌握Python中的字典(创建、访问、修改、字典方法)【详细版】
  • 数据结构之优先级队列
  • 【SQL Server数据库备份详细教程】
  • SpringSecurity Web安全配置:HttpSecurity与WebSecurityConfigurerAdapter
  • 树莓派(4B)使用教程-小白之路(NO.1)
  • 游戏引擎学习第185天
  • 02. Linux嵌入式系统学习笔记(二)(编写C程序进行文件操作、模块化编程makefile的使用)
  • 3.28日职001:大阪樱花vs浦和红钻,樱花攻守失衡,红钻有望全取三分
  • 解决Cubemx生产的 .ioc文件不能外部打开的方法
  • 格力智造的十年进击
  • 【AI学习】人工神经网络
  • Qt MSVC2017连接mysql数据库
  • 单纯形法详解
  • uniapp uni-swipe-action滑动内容排版改造
  • STM32F103_LL库+寄存器学习笔记09 - DMA串口接收与DMA串口发送,串口接收空闲中断
  • 软件需求未明确非功能性指标(如并发量)的后果
  • 聚势赋能:“人工智能+”激活高质量发展动能与生成式人工智能(GAI)认证的新机遇
  • IP 分片重组与 TCP 会话重组
  • EXPLAIN 计划中 filtered 含义及作用解析
  • stc8g1k08a软件SPI点亮屏幕MD144-QQVGA14P-01-V01(ILI9163C)测试
  • 阿里最新开源全模态大模型——Qwen2.5-Omni-7B,7B就能搞定“看听说写”,AI越来越像人了
  • 深度求索(DeepSeek):以AI之力重塑医疗未来
  • Linux—CentOS定时任务调度
  • milvus单节点安装教程