【自然语言处理|迁移学习-05】:AutoModel加载不同模型

加载和使用预训练模型的工具 - AutoModel

  • 在这里我们使用Transformers工具包进行模型的加载和使用.
  • 这些预训练模型由世界先进的NLP研发团队huggingface提供.

1 加载和使用预训练模型的步骤

第一步: 确定需要加载的预训练模型并安装依赖包.
第二步: 加载预训练模型的映射器tokenizer.
第三步: 加载带/不带头的预训练模型.
第四步: 使用模型获得输出结果.

1.1 确定需要加载的预训练模型并安装依赖包

  • 这里假设我们处理的是中文文本任务, 需要加载的模型是BERT的中文模型: bert-base-chinese
  • 在使用工具加载模型前需要安装必备的依赖包:
pip install tqdm boto3 requests regex sentencepiece sacremoses

1.2 加载预训练模型的映射器tokenizer

  • 加载tokenizer的时候,需要指定模型的类型
  • 加载所有类型的tokenizer的形式都是一样的
import torch
from transformers import AutoTokenizer, AutoModel, AutoModelForMaskedLM, AutoModelForSequenceClassification, AutoModelForQuestionAnswering

model = "./bert-base-chinese"

def demo24_1_load_tokenizer():
    tokenizer = AutoTokenizer.from_pretrained(model)
    print("tokenizer--->", tokenizer)

demo24_1_load_tokenizer()

1.3 加载带/不带头的预训练模型

  • 加载预训练模型时我们可以选择带头或者不带头的模型

  • 这里的**'头’是指模型的任务输出层, 选择加载不带头的模型, 相当于使用模型对输入文本进行特征表示**

    • 文本特征提取可以使用不带头的模型
    • AutoModel
  • 选择加载带头的模型时, 有三种类型的’头’可供选择,

    • AutoModelForMaskedLM (语言模型头)
    • AutoModelForSequenceClassification (分类模型头),
    • AutoModelForQuestionAnswering (问答模型头)
  • 不同类型的’头’, 可以使预训练模型输出指定的张量维度. 如使用’分类模型头’, 则输出尺寸为(1,2)的张量, 用于进行分类任务判定结果.

# 加载不带头的预训练模型
def demo24_2_load_model():

    # 加载的预训练模型的名字
    model_name = 'bert-base-chinese'

    print('加载不带头的预训练模型')
    model =AutoModel.from_pretrained(model_name)
    print('model--->', model)


    # 加载带有语言模型头的预训练模型
    # 适用于进行完型填空任务
    print('加载带有语言模型头的预训练模型')
    lm_model =AutoModelForMaskedLM.from_pretrained(model_name)
    print('lm_model--->', lm_model)

    # 加载带有分类模型头的预训练模型
    # 适用于文本分类任务
    print('加载带有分类模型头的预训练模型')
    classification_model = AutoModelForSequenceClassification.from_pretrained(model_name)
    print('classification_model--->', classification_model)

    # 加载带有问答模型头的预训练模型
    # 适用于阅读理解任务
    print('加载带有问答模型头的预训练模型')
    qa_model = AutoModelForQuestionAnswering.from_pretrained(model_name)
    print('qa_model--->', qa_model)

demo24_2_load_model()

1.4 使用模型获得输出结果

1.4.1 不带头的AutoModel加载模型

  • 不带头的AutoModel模型相当于提取文本的
# 使用不带头的模型进行输出

def demo24_3_load_AutoModel():

    # 加载的预训练模型的名字
    model_name = 'bert-base-chinese'

	# 1.加载tokenizer
    tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese",mirror=mirror)

    # 2 加载model
    model = AutoModel.from_pretrained(model_name)

    # 3 使用tokenizer 文本数值化
    # 输入的中文文本
    input_text = "人生该如何起头"

    # 使用tokenizer进行数值映射
    # 使用encode进行编码得到的是一个文本数值化的list
    # 文本在进行数值化的时候,会在原始文本中添加起始和结束符号
    # 如果encode中传入多个句子的列表,还会添加分隔符[SEP]
    # {CLS] - 句子的开头 - 101
    # [SEP] - 句子的结尾 - 102
    # [MASK] - 遮盖的词 - 103
    indexed_tokens = tokenizer.encode(input_text)

    # 打印映射后的结构
    print("indexed_tokens:", indexed_tokens)

    # 将映射结构转化为张量输送给不带头的预训练模型
    # 将文本进行张量化
    tokens_tensor = torch.tensor([indexed_tokens])

    # 4 使用不带头的预训练模型获得结果
    with torch.no_grad():
        encoded_layers, _ = model(tokens_tensor, return_dict=False)
        # encoded_layers, _ = model(tokens_tensor)

    print("不带头的模型输出结果:", encoded_layers)
    print("不带头的模型输出结果的尺寸:", encoded_layers.shape)

demo24_3_load_AutoModel()

  • 输出效果:
# tokenizer映射后的结果, 101和102是起止符, 
# 中间的每个数字对应"人生该如何起头"的每个字.
indexed_tokens: [101, 782, 4495, 6421, 1963, 862, 6629, 1928, 102]


不带头的模型输出结果: tensor([[[ 0.5421,  0.4526, -0.0179,  ...,  1.0447, -0.1140,  0.0068],
         [-0.1343,  0.2785,  0.1602,  ..., -0.0345, -0.1646, -0.2186],
         [ 0.9960, -0.5121, -0.6229,  ...,  1.4173,  0.5533, -0.2681],
         ...,
         [ 0.0115,  0.2150, -0.0163,  ...,  0.6445,  0.2452, -0.3749],
         [ 0.8649,  0.4337, -0.1867,  ...,  0.7397, -0.2636,  0.2144],
         [-0.6207,  0.1668,  0.1561,  ...,  1.1218, -0.0985, -0.0937]]])


# 输出尺寸为1x9x768, 即每个字已经使用768维的向量进行了表示,
# AutoModel加载模型,传入文本相当于是对文本进行特征提取,得到指定维度的特征
# 我们可以基于此编码结果进行接下来的自定义操作, 如: 编写自己的微调网络进行最终输出.

1.4.2 AutoModelForMaskedLM加载模型

  • 用于完型填空任务
def demo24_4_load_AutoLM():

    # 1 加载 tokenizer
    # 加载的预训练模型的名字
    model_name = 'bert-base-chinese'

    tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese",mirror=mirror)

    # 2 加载model
    lm_model =AutoModelForMaskedLM.from_pretrained(model_name)

    # 3 使用tokenizer 文本数值化
    # 输入的中文文本
    input_text = "人生该如何起头"

    # 使用tokenizer进行数值映射
    indexed_tokens = tokenizer.encode(input_text)

    # 打印映射后的结构
    print("indexed_tokens:", indexed_tokens)

    # 将映射结构转化为张量输送预训练模型
    tokens_tensor = torch.tensor([indexed_tokens])

    # 使用带有语言模型头的预训练模型获得结果
    with torch.no_grad():
        lm_output = lm_model(tokens_tensor,return_dict=False)

    print("带语言模型头的模型输出结果:", lm_output)
    print("带语言模型头的模型输出结果的尺寸:", lm_output[0].shape)

demo24_4_load_AutoLM()

输出效果:

带语言模型头的模型输出结果: (tensor([[[ -7.9706,  -7.9119,  -7.9317,  ...,  -7.2174,  -7.0263,  -7.3746],
         [ -8.2097,  -8.1810,  -8.0645,  ...,  -7.2349,  -6.9283,  -6.9856],
         [-13.7458, -13.5978, -12.6076,  ...,  -7.6817,  -9.5642, -11.9928],
         ...,
         [ -9.0928,  -8.6857,  -8.4648,  ...,  -8.2368,  -7.5684, -10.2419],
         [ -8.9458,  -8.5784,  -8.6325,  ...,  -7.0547,  -5.3288,  -7.8077],
         [ -8.4154,  -8.5217,  -8.5379,  ...,  -6.7102,  -5.9782,  -7.6909]]]),)

# 输出尺寸为1x9x21128, 即每个字已经使用21128维的向量进行了表示, 
# 同不带头的模型一样, 我们可以基于此编码结果进行接下来的自定义操作, 如: 编写自己的微调网络进行最终输出.
带语言模型头的模型输出结果的尺寸: torch.Size([1, 9, 21128])

1.4.3 AutoModelForClassification加载模型

  • 适用于文本分类任务
def demo24_5_load_AutoSeqC():

    # 1 加载 tokenizer
    # 加载的预训练模型的名字
    model_name = 'bert-base-chinese'

    tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese",mirror=mirror)

    # 2 加载model
    classification_model = AutoModelForSequenceClassification.from_pretrained(model_name)

    # 3 使用tokenizer 文本数值化
    # 输入的中文文本
    input_text = "人生该如何起头"

    # 使用tokenizer进行数值映射
    indexed_tokens = tokenizer.encode(input_text)

    # 打印映射后的结构
    print("indexed_tokens:", indexed_tokens)

    # 将映射结构转化为张量输送给\预训练模型
    tokens_tensor = torch.tensor([indexed_tokens])

    # 使用带有分类模型头的预训练模型获得结果
    with torch.no_grad():
        classification_output = classification_model(tokens_tensor)

    print("带分类模型头的模型输出结果:", classification_output)
    print("带分类模型头的模型输出结果的尺寸:", classification_output[0].shape)

demo24_5_load_AutoSeqC()

输出效果:

带分类模型头的模型输出结果: (tensor([[-0.0649, -0.1593]]),)
# 输出尺寸为1x2, 可直接用于文本二分问题的输出
带分类模型头的模型输出结果的尺寸: torch.Size([1, 2])

1.4.4 AutoModelForQuestionAnswering加载模型

  • 适用于抽取式问答任务
def demo24_6_load_AutoQA():

    # 1 加载 tokenizer
    # 加载的预训练模型的名字
    model_name = 'bert-base-chinese'
    tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese",mirror=mirror)

    # 2 加载model
    qa_model = AutoModelForQuestionAnswering.from_pretrained(model_name)

    # 3 使用
    # 使用带有问答模型头的模型进行输出时, 需要使输入的形式为句子对
    # 第一条句子是对客观事物的陈述
    # 第二条句子是针对第一条句子提出的问题
    # 问答模型最终将得到两个张量,
    # 每个张量中最大值对应索引的分别代表答案的在文本中的起始位置和终止位置
    input_text1 = "我家的小狗是黑色的"
    input_text2 = "我家的小狗是什么颜色的呢?"

    # 映射两个句子
    # 将question和上下文进行编码
    indexed_tokens = tokenizer.encode(input_text1, input_text2)
    print("句子对的indexed_tokens:", indexed_tokens)

    # 输出结果: [101, 2769, 2157, 4638, 2207, 4318, 3221, 7946, 5682, 4638, 102, 2769, 2157, 4638, 2207, 4318, 3221, 784, 720, 7582, 5682, 4638, 1450, 136, 102]
    
    # 设置segments_ids用于句子分段
    # 用0,1来区分第一条和第二条句子
    # 如果使用encode_plus函数就不用进行手动构建了
    segments_ids = [0] * 11 + [1] * 14

    # 转化张量形式
    segments_tensors = torch.tensor([segments_ids])
    tokens_tensor = torch.tensor([indexed_tokens]) #用于区分句子

    # 使用带有问答模型头的预训练模型获得结果
    with torch.no_grad():
    	# start_logits返回的是语料中作为开头的概率,取概率最大的作为答案的开头
    	# end_logits中概率最大的是答案的结尾
        start_logits, end_logits = qa_model(tokens_tensor, token_type_ids=segments_tensors, return_dict=False)

    print("带问答模型头的模型输出结果:", (start_logits, end_logits))
    print("带问答模型头的模型输出结果的尺寸:", (start_logits.shape, end_logits.shape))  # (torch.Size([1, 25]), torch.Size([1, 25]))

demo24_6_load_AutoQA()

输出效果:

句子对的indexed_tokens: [101, 2769, 2157, 4638, 2207, 4318, 3221, 7946, 5682, 4638, 102, 2769, 2157, 4638, 2207, 4318, 3221, 784, 720, 7582, 5682, 4638, 1450, 136, 102]

带问答模型头的模型输出结果: (tensor([[ 0.2574, -0.0293, -0.8337, -0.5135, -0.3645, -0.2216, -0.1625, -0.2768,
         -0.8368, -0.2581,  0.0131, -0.1736, -0.5908, -0.4104, -0.2155, -0.0307,
         -0.1639, -0.2691, -0.4640, -0.1696, -0.4943, -0.0976, -0.6693,  0.2426,
          0.0131]]), tensor([[-0.3788, -0.2393, -0.5264, -0.4911, -0.7277, -0.5425, -0.6280, -0.9800,
         -0.6109, -0.2379, -0.0042, -0.2309, -0.4894, -0.5438, -0.6717, -0.5371,
         -0.1701,  0.0826,  0.1411, -0.1180, -0.4732, -0.1541,  0.2543,  0.2163,
         -0.0042]]))


# 输出为两个形状1x25的张量, 他们是两条句子合并长度的概率分布,
# 第一个张量中最大值所在的索引代表答案出现的起始索引, 
# 第二个张量中最大值所在的索引代表答案出现的终止索引.
带问答模型头的模型输出结果的尺寸: (torch.Size([1, 25]), torch.Size([1, 25]))

2 小结

加载和使用预训练模型的工具:

  • 在这里我们使用transformers工具进行模型的加载和使用.
  • 这些预训练模型由世界先进的NLP研发团队huggingface提供.

加载和使用预训练模型的步骤:

  • 第一步: 确定需要加载的预训练模型并安装依赖包
  • 第二步: 加载预训练模型的映射器tokenizer
  • 第三步: 加载带/不带头的预训练模型
  • 第四步: 使用模型获得输出结果.
<think>嗯,用户问HuggingFace是不是NLP的主流框架,以及它和PyTorch有什么不同。我需要先确认HuggingFace的定位,它其实更偏向于提供预训练模型和工具库,比如Transformers库,而不是一个深度学习框架本身。PyTorch则是深度学习框架,用于构建和训练模型。 用户可能是在学习NLP的过程中,遇到了这两个工具,想了解它们的关系和区别。他们可能对HuggingFace的具体作用不太清楚,容易和PyTorch混淆。需要明确HuggingFace在生态系统中的位置,比如它如何利用PyTorch或TensorFlow来搭建模型,同时提供更高层次的抽象,比如方便的模型加载和微调接口。 另外,用户提到HuggingFace是否主流,这里需要强调它在NLP领域的主导地位,尤其是Transformers库的广泛应用。而PyTorch作为框架,是更底层的基础设施,两者相辅相成。用户可能想知道在项目中何时使用哪个工具,或者是否需要同时学习两者。需要举例说明它们的不同应用场景,比如用PyTorch定义模型结构,用HuggingFace的预训练模型进行迁移学习。 还要注意用户可能的背景,可能是刚入门NLP的开发者,需要解释清楚概念,避免技术术语过多。同时,招聘要求中可能同时提到这两个技术点,用户可能想了解它们的结合使用方式,以及为何HuggingFace在业界如此流行。需要提到社区支持、预训练模型的丰富性,以及HuggingFace提供的其他工具如Datasets、Tokenizers等,这些都是它成为主流的原因。</think>好的,我来逐步解释HuggingFace在自然语言处理(NLP)中的定位,以及它与PyTorch的区别。 --- ### **一、HuggingFace的定位:NLP领域的“基础设施”** #### **1. HuggingFace的核心价值** - **不是深度学习框架**,而是一个专注于NLP的**开源社区和工具库**。 - **核心产品**:`Transformers`库(提供预训练模型如BERT、GPT)、`Datasets`(数据集管理)、`Tokenizers`(分词工具)等。 - **主要功能**: - 提供**即用型预训练模型**(支持PyTorch、TensorFlow、JAX); - 简化模型训练、微调和部署流程; - 构建了**模型中心(Model Hub)**,允许用户共享和下载模型。 #### **2. 为什么是主流?** - **预训练模型覆盖广**:支持超10万种模型(截至2023年),涵盖文本分类、翻译、生成等任务。 - **易用性**:3行代码调用BERT: ```python from transformers import pipeline classifier = pipeline("text-classification") result = classifier("HuggingFace太好用了!") # 输出:{'label': 'POSITIVE', 'score': 0.9998} ``` - **社区生态**:企业(Google、Meta)和个人开发者共同维护,模型持续更新。 --- ### **二、HuggingFace vs PyTorch:本质区别** #### **1. PyTorch的角色** - **深度学习框架**:提供底层张量计算、自动求导、神经网络构建等功能。 - **通用性**:适用于CV、NLP、语音等多领域模型开发。 - **典型代码**:手动实现神经网络层: ```python import torch import torch.nn as nn class CustomModel(nn.Module): def __init__(self): super().__init__() self.linear = nn.Linear(768, 10) # 全连接层 def forward(self, x): return self.linear(x) ``` #### **2. HuggingFace与PyTorch的关系** - **依赖关系**:HuggingFace基于PyTorch/TensorFlow实现高层抽象。 - **协作流程**: 1. **用PyTorch定义模型结构**(或直接调用HuggingFace的`AutoModel`); 2. **用HuggingFace加载预训练权重**; 3. **用PyTorch进行训练和优化**。 --- ### **三、关键区别对比表** | **特性** | **HuggingFace** | **PyTorch** | |-------------------------|------------------------------------------|---------------------------------------| | **定位** | NLP工具库和模型中心 | 通用深度学习框架 | | **核心功能** | 预训练模型调用、微调、部署 | 张量计算、自动求导、自定义模型构建 | | **代码复杂度** | 高层API,简化实现(如`Trainer`类) | 需手动实现训练循环、模型结构 | | **适用场景** | 快速实现NLP任务(如文本分类、翻译) | 研究新模型、自定义复杂网络结构 | | **依赖关系** | 基于PyTorch/TensorFlow运行 | 独立框架,无需依赖其他库 | --- ### **四、实际项目中的协作示例** #### **场景:微调BERT模型** 1. **HuggingFace的作用**: ```python from transformers import AutoModelForSequenceClassification, Trainer model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased") # 加载预训练模型 trainer = Trainer(model=model, args=training_args, train_dataset=dataset) # 封装训练逻辑 trainer.train() # 一键训练 ``` 2. **PyTorch的作用**: - 自定义损失函数: ```python import torch.nn.functional as F class CustomLoss(nn.Module): def forward(self, outputs, labels): return F.cross_entropy(outputs.logits, labels) ``` - 手动编写训练循环(若需更精细控制)。 --- ### **五、为什么HuggingFace成为NLP主流?** 1. **降低门槛**:让开发者无需从零实现Transformer等复杂模型。 2. **标准化流程**:统一了不同模型的调用接口(如`from_pretrained()`)。 3. **模型即服务**:通过Model Hub实现模型共享,推动社区协作。 4. **扩展工具链**: - `Evaluate`:评估指标库; - `Gradio`:快速构建演示界面; - `Optimum`:优化模型部署。 --- ### **六、总结** - **HuggingFace是NLP的主流工具库**,但**不是深度学习框架**,它依赖PyTorch/TensorFlow运行。 - **区别本质**: - PyTorch是“工具箱”,提供基础工具; - HuggingFace是“预制件工厂”,提供即插即用的NLP组件。 - **学习建议**: - 掌握PyTorch以理解底层原理; - 熟练使用HuggingFace加速实际项目开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值