日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HuggingFace-transformers系列的介绍以及在下游任务中的使用

發(fā)布時間:2025/3/21 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HuggingFace-transformers系列的介绍以及在下游任务中的使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這篇博客主要面向?qū)?strong>Bert系列在Pytorch上應(yīng)用感興趣的同學(xué),將涵蓋的主要內(nèi)容是:Bert系列有關(guān)的論文,Huggingface的實現(xiàn),以及如何在不同下游任務(wù)中使用預(yù)訓(xùn)練模型。

看過這篇博客,你將了解:

  • Transformers實現(xiàn)的介紹,不同的Tokenizer和Model如何使用。
  • 如何利用HuggingFace的實現(xiàn)自定義你的模型,如果你想利用這個庫實現(xiàn)自己的下游任務(wù),而不想過多關(guān)注其實現(xiàn)細節(jié)的話,那么這篇文章將會成為很好的參考。

所需的知識

安裝Huggface庫(需要預(yù)先安裝pytorch)

在閱讀這篇文章之前,如果你能將以下資料讀一遍,或者看一遍的話,在后續(xù)的閱讀過程中將極大地減少你陷入疑惑的概率。

  • 視頻類內(nèi)容:根據(jù)排序觀看更佳
    • 李宏毅關(guān)于Elmo, Bert, GPT的講解
    • Goebels關(guān)于transformerXL的講解
    • Kilcher關(guān)于XLnet的講解
    • McCormick關(guān)于ALBERT的講解

或者,你更愿意去看論文的話:

  • 相關(guān)論文:根據(jù)排序閱讀更佳
    • arXiv:1810.04805, BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding, Authors: Jacob Devlin, Ming-Wei Chang, Kenton Lee, Kristina Toutanova
    • arXiv:1901.02860, Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context, Authors: Zihang Dai, Zhilin Yang, Yiming Yang, William W. Cohen, Jaime Carbonell, Quoc V. Le and Ruslan Salakhutdinov.
    • XLNet論文
    • ALBERT論文

HuggingFace模型加載+下游任務(wù)使用

項目組件

一個完整的transformer模型主要包含三部分:

  • Config,控制模型的名稱、最終輸出的樣式、隱藏層寬度和深度、激活函數(shù)的類別等。將Config類導(dǎo)出時文件格式為 json格式,就像下面這樣:

    {"attention_probs_dropout_prob": 0.1,"hidden_act": "gelu","hidden_dropout_prob": 0.1,"hidden_size": 768,"initializer_range": 0.02,"intermediate_size": 3072,"max_position_embeddings": 512,"num_attention_heads": 12,"num_hidden_layers": 12,"type_vocab_size": 2,"vocab_size": 30522 }

    當(dāng)然,也可以通過config.json來實例化Config類,這是一個互逆的過程。

  • Tokenizer,這是一個將純文本轉(zhuǎn)換為編碼的過程。注意,Tokenizer并不涉及將詞轉(zhuǎn)化為詞向量的過程,僅僅是將純文本分詞,添加[MASK]標記、[SEP]、[CLS]標記,并轉(zhuǎn)換為字典索引。Tokenizer類導(dǎo)出時將分為三個文件,也就是:

    • vocab.txt

      詞典文件,每一行為一個詞或詞的一部分

    • special_tokens_map.json 特殊標記的定義方式

      {"unk_token": "[UNK]", "sep_token": "[SEP]", "pad_token": "[PAD]", "cls_token": "[CLS]", "mask_token": "[MASK]"}
    • tokenizer_config.json 配置文件,主要存儲特殊的配置。

  • Model,也就是各種各樣的模型。除了初始的Bert、GPT等基本模型,針對下游任務(wù),還定義了諸如BertForQuestionAnswering等下游任務(wù)模型。模型導(dǎo)出時將生成config.json和pytorch_model.bin參數(shù)文件。前者就是1中的配置文件,這和我們的直覺相同,即config和model應(yīng)該是緊密聯(lián)系在一起的兩個類。后者其實和torch.save()存儲得到的文件是相同的,這是因為Model都直接或者間接繼承了Pytorch的Module類。從這里可以看出,HuggingFace在實現(xiàn)時很好地尊重了Pytorch的原生API。

  • 導(dǎo)入Bert系列基本模型的方法

    通過官網(wǎng)自動導(dǎo)入

    官方文檔中初始教程提供的方法為:

    # Load pre-trained model (weights) # model = BertModel.from_pretrained('bert-base-uncased')

    這個方法需要從官方的s3數(shù)據(jù)庫下載模型配置、參數(shù)等信息(代碼中已配置好位置)。這個方法雖然簡單,但是在國內(nèi)并不可用。當(dāng)然你可以先嘗試一下,不過會有很大的概率無法下載模型。

    手動下載模型信息并導(dǎo)入

  • 在HuggingFace官方模型庫上找到需要下載的模型,點擊模型鏈接, 這個例子使用的是bert-base-uncased模型

  • 點擊List all files in model,將其中的文件一一下載到同一目錄中。例如,對于XLNet:

    # List of model files config.json 782.0B pytorch_model.bin 445.4MB special_tokens_map.json 202.0B spiece.model 779.3KB tokenizer_config.json 2.0B

    但是這種方法有時也會不可用。如果您可以將Transformers預(yù)訓(xùn)練模型上傳到迅雷等網(wǎng)盤的話,請在評論區(qū)告知,我會添加在此博客中,并為您添加博客友鏈。

  • 通過下載好的路徑導(dǎo)入模型:

    import transformers MODEL_PATH = r"D:\transformr_files\bert-base-uncased/" # a.通過詞典導(dǎo)入分詞器 tokenizer = transformers.BertTokenizer.from_pretrained(r"D:\transformr_files\bert-base-uncased\bert-base-uncased-vocab.txt") # b. 導(dǎo)入配置文件 model_config = transformers.BertConfig.from_pretrained(MODEL_PATH) # 修改配置 model_config.output_hidden_states = True model_config.output_attentions = True # 通過配置和路徑導(dǎo)入模型 model = transformers.BertModel.from_pretrained(MODEL_PATH,config = model_config)
  • 利用分詞器分詞

    利用分詞器進行編碼

    • 對于單句:

      # encode僅返回input_ids tokenizer.encode("i like you") Out : [101, 1045, 2066, 2017, 102]
    • 對于多句:

      # encode_plus返回所有編碼信息 tokenizer.encode_plus("i like you", "but not him") Out : {'input_ids': [101, 1045, 2066, 2017, 102, 2021, 2025, 2032, 102],'token_type_ids': [0, 0, 0, 0, 0, 1, 1, 1, 1],'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]}

    模型的所有分詞器都是在PreTrainedTokenizer中實現(xiàn)的,分詞的結(jié)果主要有以下內(nèi)容:

    { input_ids: list[int], token_type_ids: list[int] if return_token_type_ids is True (default) attention_mask: list[int] if return_attention_mask is True (default) overflowing_tokens: list[int] if a max_length is specified and return_overflowing_tokens is True num_truncated_tokens: int if a max_length is specified and return_overflowing_tokens is True special_tokens_mask: list[int] if add_special_tokens if set to True and return_special_tokens_mask is True }

    編碼解釋:

    • 'input_ids':顧名思義,是單詞在詞典中的編碼
    • 'token_type_ids', 區(qū)分兩個句子的編碼
    • 'attention_mask', 指定對哪些詞進行self-Attention操作
    • 'overflowing_tokens', 當(dāng)指定最大長度時,溢出的單詞
    • 'num_truncated_tokens', 溢出的token數(shù)量
    • 'return_special_tokens_mask',如果添加特殊標記,則這是[0,1]的列表,其中0指定特殊添加的標記,而1指定序列標記

    將分詞結(jié)果輸入模型,得到編碼

    # 添加batch維度并轉(zhuǎn)化為tensor input_ids = torch.tensor([input_ids]) token_type_ids = torch.tensor([token_type_ids]) # 將模型轉(zhuǎn)化為eval模式 model.eval() # 將模型和數(shù)據(jù)轉(zhuǎn)移到cuda, 若無cuda,可更換為cpu device = 'cuda' tokens_tensor = input_ids.to(device) segments_tensors = token_type_ids.to(device) model.to(device)# 進行編碼 with torch.no_grad():# See the models docstrings for the detail of the inputsoutputs = model(tokens_tensor, token_type_ids=segments_tensors)# Transformers models always output tuples.# See the models docstrings for the detail of all the outputs# In our case, the first element is the hidden state of the last layer of the Bert modelencoded_layers = outputs # 得到最終的編碼結(jié)果encoded_layers

    Bert最終輸出的結(jié)果為:

    sequence_output, pooled_output, (hidden_states), (attentions)

    以輸入序列長度為14為例

    index名稱維度描述
    0sequence_outputtorch.Size([1, 14, 768])輸出序列
    1pooled_outputtorch.Size([1, 768])對輸出序列進行pool操作的結(jié)果
    2(hidden_states)tuple,13*torch.Size([1, 14, 768])隱藏層狀態(tài)(包括Embedding層),取決于modelconfig中output_hidden_states
    3(attentions)tuple,12*torch.Size([1, 12, 14, 14])注意力層,取決于參數(shù)中output_attentions

    Bert總結(jié)

    這一節(jié)我們以Bert為例對模型整體的流程進行了了解。之后的很多模型都基于Bert,并基于Bert進行了少量的調(diào)整。其中的輸出和輸出參數(shù)也有很多重復(fù)的地方。

    利用預(yù)訓(xùn)練模型在下游任務(wù)上微調(diào)

    如開頭所說,這篇文章重點在于"如何進行模型的調(diào)整以及輸入輸出的設(shè)定", 以及"Transformer的實現(xiàn)進行簡要的提及", 所以,我們不會去介紹、涉及如何寫train循環(huán)等話題,而僅僅專注于模型。也就是說,我們將止步于跑通一個模型,而不計批量數(shù)據(jù)預(yù)處理、訓(xùn)練、驗證等過程。

    同時,這里更看重如何基于Bert等初始模型在實際任務(wù)上進行微調(diào),所以我們不會僅僅地導(dǎo)入已經(jīng)在下游任務(wù)上訓(xùn)練好的模型參數(shù),因為在這些模型上使用的方法和上一章的幾乎完全相同。

    這里的輸入和輸入以模型的預(yù)測過程為例。

    問答任務(wù) via Bert

    模型的構(gòu)建

    from transformers import BertTokenizer, BertForQuestionAnswering import torchMODEL_PATH = r"D:\transformr_files\bert-base-uncased/" # 實例化tokenizer tokenizer = BertTokenizer.from_pretrained(r"D:\transformr_files\bert-base-uncased\bert-base-uncased-vocab.txt") # 導(dǎo)入bert的model_config model_config = transformers.BertConfig.from_pretrained(MODEL_PATH) # 首先新建bert_model bert_model = transformers.BertModel.from_pretrained(MODEL_PATH,config = model_config) # 最終有兩個輸出,初始位置和結(jié)束位置(下面有解釋) model_config.num_labels = 2 # 同樣根據(jù)bert的model_config新建BertForQuestionAnswering model = BertForQuestionAnswering(model_config) model.bert = bert_model

    一般情況下,一個基本模型對應(yīng)一個Tokenizer, 所以并不存在對應(yīng)于具體下游任務(wù)的Tokenizer。這里通過bert_model初始化BertForQuestionAnswering。

    任務(wù)輸入:問題句,答案所在的文章?"Who was Jim Henson?", "Jim Henson was a nice puppet"

    任務(wù)輸出:答案?"a nice puppet"

    # 設(shè)定模式 model.eval() question, text = "Who was Jim Henson?", "Jim Henson was a nice puppet" # 獲取input_ids編碼 input_ids = tokenizer.encode(question, text) # 手動進行token_type_ids編碼,可用encode_plus代替 token_type_ids = [0 if i <= input_ids.index(102) else 1 for i in range(len(input_ids))] # 得到評分, start_scores, end_scores = model(torch.tensor([input_ids]), token_type_ids=torch.tensor([token_type_ids])) # 進行逆編碼,得到原始的token all_tokens = tokenizer.convert_ids_to_tokens(input_ids) #['[CLS]', 'who', 'was', 'jim', 'henson', '?', '[SEP]', 'jim', 'henson', 'was', 'a', 'nice', 'puppet', '[SEP]']

    模型輸入:inputids, token_type_ids

    模型輸出:start_scores, end_scores 形狀都為torch.Size([1, 14]),其中14為序列長度,代表每個位置是開始/結(jié)束位置的概率。

    將模型輸出轉(zhuǎn)化為任務(wù)輸出:

    # 對輸出的答案進行解碼的過程 answer = ' '.join(all_tokens[torch.argmax(start_scores) : torch.argmax(end_scores)+1]) # assert answer == "a nice puppet" # 這里因為沒有經(jīng)過微調(diào),所以效果不是很好,輸出結(jié)果不佳。 print(answer) # 'was jim henson ? [SEP] jim henson was a nice puppet [SEP]'

    文本分類任務(wù)(情感分析等) via XLNet

    模型的構(gòu)建

    from transformers import XLNetConfig, XLNetModel, XLNetTokenizer, XLNetForSequenceClassification import torch # 定義路徑,初始化tokenizer XLN_PATH = r"D:\transformr_files\XLNetLMHeadModel" tokenizer = XLNetTokenizer.from_pretrained(XLN_PATH) # 加載配置 model_config = XLNetConfig.from_pretrained(XLN_PATH) # 設(shè)定類別數(shù)為3 model_config.num_labels = 3 # 直接從xlnet的config新建XLNetForSequenceClassification(和上一節(jié)方法等效) cls_model = XLNetForSequenceClassification.from_pretrained(XLN_PATH, config=model_config)

    任務(wù)輸入:句子?"i like you, what about you"

    任務(wù)輸出:句子所屬的類別?class1

    # 設(shè)定模式 model.eval() token_codes = tokenizer.encode_plus("i like you, what about you")

    模型輸入:inputids, token_type_ids

    模型輸出:logits, hidden states, 其中l(wèi)ogits形狀為torch.Size([1, 3]), 其中的3對應(yīng)的是類別的數(shù)量。當(dāng)訓(xùn)練時,第一項為loss。

    其他的任務(wù),將繼續(xù)更新

    其他的模型和之前的兩個大致是相同的,你可以自己發(fā)揮。我會繼續(xù)在相關(guān)的庫上進行實驗,如果發(fā)現(xiàn)用法不一樣的情況,將會添加在這里。

    參考

    本文章主要對HuggingFace庫進行了簡要介紹。具體安裝等過程請參見官方github倉庫。

    總結(jié)

    以上是生活随笔為你收集整理的HuggingFace-transformers系列的介绍以及在下游任务中的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。