Huggingface初上手即ERNIE-gram句子相似性實戰

Milkha發表於2024-02-29

大模型如火如荼的今天,不學點語言模型(LM)相關的技術實在是說不過去了。只不過由於過往專案用到LM較少,所以學習也主要停留在直面——動眼不動手的水平。Huggingface(HF)也是現在搞LM離不開的工具了。

出於專案需要,以及實踐出真知的想法,在此記錄一下第一次使用HF和微調ERNIE-gram的過程。

目錄
  • 開始的開始
  • 模型選擇
  • 如何使用選好的模型
  • 怎麼微調
    • 模型定義
    • 訓練流程
  • 參考

開始的開始

HF已經做的很好了。但是對於第一次上手實操LM的我來說,還是有點陌生的。上手時有幾個問題是一直困擾我的:

  • HF上這麼多模型,我該用哪一個?
  • 每個LM的主要作用是對文字進行Embedding,可我的任務是句子對相似性計算,這該怎麼搞?
  • 我想在自己的資料上繼續微調模型,該怎麼做?

模型選擇

簡單描述一下我的任務:給定兩個句子,判斷兩個句子的語義是否等價

從NLP的角度出發,這是一類STS(Semantic Textual Similarity)任務,本質是在比較兩個文字的語義是否相似。透過檢索,找到了一些相關的比賽,例如問題匹配的比賽和相關的模型,這裡簡單羅列一下:

  • 千言資料集:問題匹配魯棒性
  • 千言-問題匹配魯棒性評測基線
  • Quora Question Pairs
  • ATEC學習賽:NLP之問題相似度計算
  • 第三屆魔鏡杯大賽—— 語義相似度演算法設計
  • LCQMC通用領域問題匹配資料集
  • [Chinese-BERT-wwm]。

透過以上資料,我大致確定了我要使用的模型——ERNIE-Gram[1]

如何使用選好的模型

首先,我找到了ERNIE-Gram的程式碼倉庫[2]。程式碼裡開源了模型的結構以及微調的程式碼,相對來說還是比較齊全的。但是有一個最不方便的地方——它是用飛漿寫的(不是說飛漿不好,只是一直以來都用pytorch)。當然,很快我又找到了pytorch版的ERNIE-Gram,並且在HF找到了ERNIE-Gram模型。如果我知道怎麼使用HF,那麼或許我可以很快開始我的微調了,可惜沒有如果。

那怎麼使用HF上的模型,在自己的資料上進行微調呢?

找到了一篇比較合適的參考資料[3],其中介紹瞭如何在HF中呼叫ERNIE模型:

from transformers import BertTokenizer, ErnieModel
tokenizer = BertTokenizer.from_pretrained("nghuyong/ernie-1.0-base-zh")
model = ErnieModel.from_pretrained("nghuyong/ernie-1.0-base-zh")

根據這個,我發現透過HF使用某個模型的方法是從transformers庫中匯入對應的模型和工具即可。那麼,我只需要找到對應的模型名和工具,然後以此作為基座,再新增一些可訓練層就可以了?

分析dir(transformers)看看都有哪些和Ernie相關的類:

d = dir(transformers)
dd = [e for e in d if 'ernie' in e.lower()]
len(dd)  # 26
print(dd)
# ====
['ERNIE_M_PRETRAINED_CONFIG_ARCHIVE_MAP', 'ERNIE_M_PRETRAINED_MODEL_ARCHIVE_LIST', 'ERNIE_PRETRAINED_CONFIG_ARCHIVE_MAP', 'ERNIE_PRETRAINED_MODEL_ARCHIVE_LIST', 'ErnieConfig', 'ErnieForCausalLM', 'ErnieForMaskedLM', 'ErnieForMultipleChoice', 'ErnieForNextSentencePrediction', 'ErnieForPreTraining', 'ErnieForQuestionAnswering', 'ErnieForSequenceClassification', 'ErnieForTokenClassification', 'ErnieMConfig', 'ErnieMForInformationExtraction', 'ErnieMForMultipleChoice', 'ErnieMForQuestionAnswering', 'ErnieMForSequenceClassification', 'ErnieMForTokenClassification', 'ErnieMModel', 'ErnieMPreTrainedModel', 'ErnieMTokenizer', 'ErnieModel', 'ErniePreTrainedModel', 'models.ernie', 'models.ernie_m']

為了更好了解每個類是幹啥的,直接上transformers庫來看各個類的介紹[4]。很快啊,我就發現ErnieForSequenceClassification很適合我的任務:

image-20240227181634595

圖中的GLUE(General Language Understanding Evaluation )[5]是一系列評測任務集合,顯然,我的任務屬於Similarity那一類。

image-20240227182050635

很好,大致可以確定該怎麼使用HF上的Ernie-Gram模型來完成我的任務了(可惜沒有對應的示例)。

怎麼微調

在實操之前,對於在預訓練好的模型上進行微調,我的想法是:把預訓練模型包起來,新增一個分類層,學習分類層的引數就可以了。

但是如果我選擇了ErnieForSequenceClassification,透過原始碼可以發現該類其實是在ErnieModel的基礎上新增了一個分類層,那我是否直接載入模型後,選擇訓練哪些引數就可以了呢?

image-20240227184848206

其實,廣義的來說,這等價於一個問題:在HuggingFace中如何微調模型?[6][7][8]

其實,微調和平常的模型訓練沒有太大區別,只不過需要載入預訓練好的模型,以及利用現成的工具搭建訓練流程,其中主要涉及到的就兩點:模型的定義、訓練流程的搭建。

模型定義

由於transformers中已經定義好了很多模型,如果某個完全符合要求,那就可以直接使用了。根據自己的需求,選擇凍結和訓練哪些引數就可以了。

但是有些時候只是用預訓練的模型作為自己模型的一部分,這個時候就需要我們做一些額外的工作了——把預訓練模型作為一塊積木,搭建我們自己的模型。正如ErnieForSequenceClassification所做的一樣。

訓練流程

訓練流程類似。可以重頭自己搭建訓練流程,或者使用transformes自帶的Trainer介面。

這裡直接參考HF的教程即可:Fine-tuning a model with the Trainer API自己搭建訓練流程

參考


  1. ERNIE-Gram: Pre-Training with Explicitly N-Gram Masked Language Modeling for Natural Language Understanding, NAACL-HLT, 2021. ↩︎

  2. ernie-gram. ↩︎

  3. 試試在transformers中呼叫ERNIE. ↩︎

  4. Hugging Face Ernie Doc`` ↩︎

  5. GLUE: A MULTI-TASK BENCHMARK AND ANALYSIS PLATFORM FOR NATURAL LANGUAGE UNDERSTANDING, ICLR, 2019. ↩︎

  6. Hugging Face 的 Transformers 庫快速入門(四):微調預訓練模型. ↩︎

  7. HuggingFace | 在HuggingFace中如何微調模型. ↩︎

  8. FINE-TUNING A PRETRAINED MODEL. ↩︎

相關文章