無痛使用超強NLP model — BERT

Sentence Transformers 使用方法介紹

倢愷 Oscar
10 min readApr 21, 2021

--

近三年來在NLP(自然語言處理)的研究領域中,大多數的Model都跟一個名字有關,那就是BERT。

BERT的威力大多數人一直都知道,但是其實並不多人使用過它,最主要有2個困難

  1. BERT跟以往的NLP model(像是RNN、或是Tfidf+ML model)使用起來相對麻煩,大部分ML engineer如果不是對tensorflow或是pytorch特別熟悉,都要花不少的時間學習。
  2. BERT需要的運算資源非常龐大,不論是Training還是inference。

而這兩個問題,都已經很多方案可以處理,像是運算資源過大的問題,現在已經有非常多Model Distillation的研究在壓縮BERT的大小,而使用麻煩的問題則已經有了Sentence Transformers,幫助我們快速使用

這也導致了在近兩年的Kaggle比賽或是新創的project中,使用BERT的比例越來越高,而我認為接下來BERT會變得像是Word2Vec一樣,是每個NLP engineer必須了解的常識。

BERT是2021年必備的NLP model

具體BERT的原理細節跟為甚麼那麼強大我在這邊先不說明,之後有時間再寫一篇快速整理相關知識。

這篇文章我會講解1. 甚麼是Language Modeling
2. Sentence-Transformers安裝
3. Sentence-Transformers使用方法介紹
4. Sentence-Transformers處理中文

甚麼是Language Modeling

Language Modeling很有可能是近幾年來NLP界最重大的想法,近幾年大部分很強大的NLP model包含BERT、GPT3都是使用Language Modeling的技術。

具體Language Modeling是甚麼???

先來談談在我各篇Medium裡面,不斷重複強調的一件事,在業界我們使用ML最大的困境就是 — 沒有Data

而NLP的labeled data又比CV更難取得,想像如果你今天要收集一個句子翻譯的Data,光是收集Data,我們可能就要請專業的翻譯員,日以繼夜的進行翻譯,可能一個小時能夠翻譯一篇3000字的文章就算不錯了(我隨便估的),而我們可能花費數個月,終於收集好一個dataset,裡面有10000個文章,而每個文章都是1000字上下。

現在我們要train一個NLP的model來學習這個dataset,結果發現學不起來

為甚麼?因為語言翻譯這件事本身太難了,只有10000筆資料是不夠的,我們的模型要學會翻譯要同時學會三件事

  1. 理解A語言的文義
  2. 書寫B語言的文章
  3. 把A語言的知識對應到B語言中

而這三件事裡面的任何一件都是人類花數年學習才掌握的知識,ML model很難以10000筆Data就學習起來。

NLP Labeled data超級難取得,但卻通常需要很大量

而Language Modeling就做了一件非常非常有趣的假設

NLP的Labeled Data不好取得,但是Unlabeled Data卻一大堆
所以真正的問題在於我們怎麼利用Unlabeled Data。

這邊講的Unlabeled Data一大堆包含著像是各大論壇網友的各種流言、Wikipedia的文章內容、各式書籍的內容…

而Language Modeling運用Unlabeled Data的方法相當簡單。

讓我們的模型去學會「預測下一個字」

簡單來講就是給文章的前N個字,請模型預測第N+1個字是甚麼
而因為第N+1個字我們本身文章中就有,所以不用Label!!

對照我們日常生活經驗,我們藉由不斷的看文章、寫文章就可以對一個語言的知識累積越來越深,而這正是Language Modeling做的事情。

而實際上Langauge Modeling這個想法在NLP界已經行之有年,包含過去RNN甚至更古早的N-gram model時代都會做這件事,只是隨著現在DL Model能力越來越強,Language Modeling能夠學到的事情越來越多!!

而BERT這些Model就是基於Language Modeling,預訓練在非常非常龐大的資料集上(像是GPT2就爬網路上各大論壇的文字下來學習),預訓練完後,模型已經具備了很多語言的知識、常識,再讓BERT去學習各種具體的問題,效果就遠超以前的方法。

具體BERT細節有興趣請回復告訴我,如果數量夠多,我會再寫文章說明

Sentence-Transformers安裝

在過去要使用BERT最少要懂得使用pytorch或是Tensorflow其中一個框架,而現在有網路上的善心人士幫我們把使用BERT的常見操作都整理成了一個Package,而這就是Sentence-Transformer

安裝Sentence Transformer非常容易

pip install -U sentence-transformers

不過這邊有個小細節,因為Sentence-Transformers本身會使用到pytorch,所以如果原本環境裡沒有pytorch他會幫你裝。

如果你想要pytorch使用cuda的話,最好還是手動裝pytorch並且指定好特定的cuda版本。

可以參考這個網站

Sentence-Transformers使用方法介紹

Sentence-Transformers使用分兩個部分

  1. 使用Pretrained Model進行Inference
  2. Train你自己的BERT的model

這裡主要講第一個部分:使用Pretrained Model進行Inference

第一步 Load Model,這邊如果是沒有Load過的Model的話,會自動跑一次下載。

from sentence_transformers import SentenceTransformer
model = SentenceTransformer('paraphrase-distilroberta-base-v1')

第二步 Encode BERT Embedding,這邊我用官方的假資料來做Embedding

sentences = ['This framework generates embeddings for each input sentence', 'Sentences are passed as a list of string.', 'The quick brown fox jumps over the lazy dog.']
sentence_embeddings = model.encode(sentences)

而在做完這步之後sentence_embeddings這個output,會是一個numpy ndarray

sentence_embeddings.shape
### (3, 768)
### 第一個維度3代表我們總共embed了3個句子
### 而每個句子變成一個768維的vector

第三步,做我們後續要做的事情

當我們有每個句子的Embedding後,最常見的我們就可以算每兩個句子之間的similarity,而有similarity我們就可以做searching、clustering…。

除此之外我們也可以用xgboost之類的ML model來快速train一個downstream task(這相對比較少做,如果我們要train的話更常見是直接finetune整個BERT)

第四步(不一定要做),通常我會做dimension reduction

因為BERT embedding的維度動輒就是500 700,後續運算不易,我一般會直接用PCA來做dimension reduction。

而實際上Sentence-Transformers有很多已經針對特定問題預訓練好的Model了,後面舉兩個例子。

Image Search = 給定文字敘述,看跟圖像內容是否相似。

使用’clip-ViT-B-32'這個model就可以同時encode圖片跟文字,並且兩個出來的embedding可以直接算similarity,得到文字敘述跟圖像內容的相似程度

from sentence_transformers import SentenceTransformer, util
from PIL import Image

#Load CLIP model
model = SentenceTransformer('clip-ViT-B-32')

#Encode an image:
img_emb = model.encode(Image.open('two_dogs_in_snow.jpg'))

#Encode text descriptions
text_emb = model.encode(['Two dogs in the snow', 'A cat on a table', 'A picture of London at night'])

#Compute cosine similarities
cos_scores = util.cos_sim(img_emb, text_emb)
print(cos_scores)

Extractive Summarization = 給文章,Model從裡面選幾句話當成這個文章的摘要

這邊可以直接參考官方的example

Sentence-Transformers處理中文

如果要使用Sentence-Transformers處理中文的話,就要load裡面的Multilingual Model近來,可以參考下面頁面。

我自己最常用的是paraphrase-xlm-r-multilingual-v1這個Model,不過他大小1G,相對比較臃腫

model = SentenceTransformer('paraphrase-xlm-r-multilingual-v1')

其他像是distiluse-base-multilingual-cased-v2效果也非常好。

使用在非英文上的時候要特別注意,即便你今天使用的Model沒有支援你的語系,他還是會製造出Embedding,只是是非常非常爛的Embedding。

所以一般我會用非常簡單的word pair去測試現在的Embedding有沒有正確運作。(這一步非常重要,針對特定Project我會整理出越來越複雜的Pair來測試)

下面給範例code

BERT類型的Embedding在近幾年的NLP kaggle比賽或是NLP的新創project越來越普及,如果想要入門,或是在目前的Project快速導入相關技術的話,Sentence-Transformers是一個非常好用的Package推薦給大家,裡面不只BERT,RoBERTa、XLM等非常powerful的model都有。

如果喜歡這篇文章可以幫我多拍手幾次XD,或是對於哪個類型文章有興趣都可以在留言區跟我講~ 後續會以中難度的ML/DS/AI知識為主,以及AI/HCI研究相關知識

我現在在整理一般課程、書籍不會提到但是很重要的DS、ML知識,有興趣可以關注我,並且隨時關注我的文章目錄。

--

--

倢愷 Oscar

我是倢愷,CTO at TeraThinker an AI Adaptive Learning System Company。AI/HCI研究者,超過100場的ML、DL演講、workshop經驗。主要學習如何將AI落地於業界。 有家教、演講合作,可以email跟我聯絡:axk51013@gmail.com