两行代码玩转 Google BERT 句向量词向量
關(guān)于作者:肖涵博士,bert-as-service 作者。現(xiàn)為騰訊 AI Lab 高級(jí)科學(xué)家、德中人工智能協(xié)會(huì)主席。肖涵的 Fashion-MNIST 數(shù)據(jù)集已成為機(jī)器學(xué)習(xí)基準(zhǔn)集,在 Github 上超過 4.4K 星,一年來其學(xué)術(shù)引用數(shù)超過 300 篇。
肖涵在德國(guó)慕尼黑工業(yè)大學(xué)計(jì)算機(jī)系取得了計(jì)算機(jī)博士(2014)和碩士學(xué)位(2011),在北郵取得了信息通信學(xué)士學(xué)位(2009)。他曾于 2014-2018 年初就職于位于德國(guó)柏林的 Zalando 電商,先后在其推薦組、搜索組和 Research 組擔(dān)任高級(jí)數(shù)據(jù)科學(xué)家。肖涵所創(chuàng)辦的德中人工智能協(xié)會(huì)(GCAAI)如今擁有 400 余名會(huì)員,致力于德中兩國(guó) AI 領(lǐng)域的合作與交流,是德國(guó)最具影響力的新型團(tuán)體之一。
WeChat: hxiao1987?
Blog: https://hanxiao.github.io?
德中人工智能協(xié)會(huì): https://gcaai.org?
Google AI 幾周前發(fā)布的 BERT (Bidirectional Encoder Representations from Transformers) 模型在 NLP 圈掀起了軒然大波,其使用超多層 Transformer + 雙任務(wù)預(yù)訓(xùn)練 + 后期微調(diào)的訓(xùn)練策略,在 11 個(gè)不同類型的 NLP 任務(wù)上刷新了紀(jì)錄。
Google 隨后在 Github 上開源了 BERT 的代碼,并提供了在維基百科語料上使用 TPU 預(yù)訓(xùn)練好的模型供大家下載。這其中也包括了基于字符級(jí)別的中文 BERT 預(yù)訓(xùn)練模型。?
BERT開源代碼:
https://github.com/google-research/bert
bert-as-service 能讓你簡(jiǎn)單通過兩行代碼,即可使用預(yù)訓(xùn)練好的模型生成句向量和 ELMo 風(fēng)格的詞向量:?
你可以將 bert-as-service 作為公共基礎(chǔ)設(shè)施的一部分,部署在一臺(tái) GPU 服務(wù)器上,使用多臺(tái)機(jī)器從遠(yuǎn)程同時(shí)連接實(shí)時(shí)獲取向量,當(dāng)做特征信息輸入到下游模型。
回顧:BERT的訓(xùn)練機(jī)制
BERT 模型的訓(xùn)練分為預(yù)訓(xùn)練(Pre-training)和微調(diào)(Pre-training)兩步。預(yù)訓(xùn)練和下游任務(wù)無關(guān),卻是一個(gè)非常耗時(shí)耗錢的過程。Google 坦言,對(duì) BERT 的預(yù)訓(xùn)練一般需要 4 到 16 塊 TPU 和一周的時(shí)間,才可以訓(xùn)練完成。
慶幸的是,大部分 NLP 研究者只需使用 Google 發(fā)布的預(yù)訓(xùn)練模型,而不需要重復(fù)這一過程。你可以把預(yù)訓(xùn)練模型想象成一個(gè) Prior,是對(duì)語言的先驗(yàn)知識(shí),一旦擁有就不需要重復(fù)構(gòu)造。?
微調(diào)取決于下游的具體任務(wù)。不同的下游任務(wù)意味著不同的網(wǎng)絡(luò)擴(kuò)展結(jié)構(gòu):比如一個(gè)對(duì)句子進(jìn)行情感分類的任務(wù),只需要在 BERT 的輸出層句向量上接入幾個(gè) Dense 層,走個(gè) softmax。而對(duì)于 SQuAD 上的閱讀理解任務(wù),需要對(duì) BERT 輸出的詞向量增加 match 層和 softmax。
總體來說,對(duì) BERT 的微調(diào)是一個(gè)輕量級(jí)任務(wù),微調(diào)主要調(diào)整的是擴(kuò)展網(wǎng)絡(luò)而非 BERT 本身。 換句話說,我們完全可以固定住 BERT 的參數(shù),把 BERT 輸出的向量編碼當(dāng)做一個(gè)特征(feature)信息,用于各種下游任務(wù)。?
無論下游是什么任務(wù),對(duì)于 NLP 研究者來說,最重要的就是獲取一段文字或一個(gè)句子的定長(zhǎng)向量表示,而將變長(zhǎng)的句子編碼成定長(zhǎng)向量的這一過程叫做 sentence encoding/embedding。?
bert-as-service 正是出于此設(shè)計(jì)理念,將預(yù)訓(xùn)練好的 BERT 模型作為一個(gè)服務(wù)獨(dú)立運(yùn)行,客戶端僅需通過簡(jiǎn)單的 API 即可調(diào)用服務(wù)獲取句子、詞級(jí)別上的向量。在實(shí)現(xiàn)下游任務(wù)時(shí),無需將整個(gè) BERT 加載到 tf.graph 中,甚至不需要 TensorFlow 也不需要 GPU,就可以在 scikit-learn, PyTorch, Numpy 中直接使用 BERT。
bert-as-service
bert-as-service 將 BERT模型作為一個(gè)獨(dú)立的句子編碼(sequence encoding/embedding)服務(wù),在客戶端僅用兩行代碼就可以對(duì)句子進(jìn)行高效編碼。其主要特色如下:?
state-of-the-art:基于 Google 最新發(fā)布的 BERT 模型;
易用:客戶端僅需簡(jiǎn)單兩行代碼即可調(diào)用;?
快速:每秒 780 個(gè)句子(見詳細(xì)評(píng)測(cè));
并發(fā)性:自動(dòng)擴(kuò)展到多塊 GPU,多客戶端,高效任務(wù)調(diào)度,無延遲(見針對(duì)多客戶端并發(fā)的評(píng)測(cè))。
速度評(píng)測(cè):
https://github.com/hanxiao/bert-as-service#Benchmark
并發(fā)評(píng)測(cè):
https://github.com/hanxiao/bert-as-service#speed-wrt-num_client
使用方法
1. 下載 Google 發(fā)布的預(yù)訓(xùn)練 BERT 模型
從下方鏈接下載 Google 發(fā)布的預(yù)訓(xùn)練模型,解壓到某個(gè)路徑下,比如:?/tmp/english_L-12_H-768_A-12/?
預(yù)訓(xùn)練模型下載:
https://github.com/google-research/bert#pre-trained-models
你可以使用包括?BERT-Base, Multilingual?和?BERT-Base, Chinese?在內(nèi)的任意模型。
2. 開啟 BERT 服務(wù)
這個(gè)代碼將開啟一個(gè) 4 進(jìn)程的 BERT 服務(wù),意味著它可以最高處理來自 4 個(gè)客戶端的并發(fā)請(qǐng)求。雖然同一時(shí)刻連接服務(wù)的客戶端數(shù)量沒有限制,但在某時(shí)刻多余 4 個(gè)的并發(fā)請(qǐng)求將被暫時(shí)放到一個(gè)負(fù)載均衡中,等待執(zhí)行。有關(guān) bert-as-service 背后的架構(gòu)可以參考 FAQ 和并發(fā)客戶端性能評(píng)測(cè)。
3. 使用客戶端獲取句子向量編碼
對(duì)于客戶端來說,你唯一需要的文件就是 service/client.py ,因?yàn)槲覀冃枰獜闹袑?dǎo)入 BertClient 。
bc?=?BertClient()
bc.encode(['First?do?it',?'then?do?it?right',?'then?do?it?better'])
這會(huì)返回一個(gè) 3 x 768 的?ndarray 結(jié)構(gòu),每一行代表了一句話的向量編碼。你也可以通過設(shè)置,讓其返回 Python 類型的 List[List[float]] 。
在另一臺(tái)機(jī)器上使用 BERT 服務(wù)
客戶端也可以從另一臺(tái)機(jī)器上連接 BERT 服務(wù),只需要一個(gè) IP 地址和端口號(hào):
from?service.client?import?BertClient
bc?=?BertClient(ip='xx.xx.xx.xx',?port=5555)??#?ip?address?of?the?GPU?machine
bc.encode(['First?do?it',?'then?do?it?right',?'then?do?it?better'])
你還可以把服務(wù)架設(shè)在 docker container 中使用,詳情可以參考項(xiàng)目的 README.md。bert-as-service 所支持的 C/S 模式可以用下圖總結(jié):
性能評(píng)測(cè)
作為一個(gè)基礎(chǔ)服務(wù),速度和伸縮性(scalability)非常關(guān)鍵。只有當(dāng)下游的模型能夠通過其快速流暢地獲取數(shù)據(jù)時(shí),該服務(wù)的意義才能得到最大體現(xiàn)。BERT 的網(wǎng)絡(luò)復(fù)雜度眾所周知,那么 bert-as-service 能否達(dá)到工程級(jí)別的速度?為了驗(yàn)證這一點(diǎn),我們做了如下方面的評(píng)測(cè)。
?max_seq_len?對(duì)速度的影響
?max_seq_len 是服務(wù)端的一個(gè)參數(shù),用來控制 BERT 模型所接受的最大序列長(zhǎng)度。當(dāng)輸入的序列長(zhǎng)度長(zhǎng)于 max_seq_len 時(shí),右側(cè)多余字符將被直接截?cái)唷K匀绻阆胩幚砗荛L(zhǎng)的句子,服務(wù)器端正確設(shè)置 max_seq_len 是其中一個(gè)關(guān)鍵指標(biāo)。而從性能上來講,過大的 max_seq_len 會(huì)拖慢計(jì)算速度,并很有可能造成內(nèi)存 OOM。
?client_batch_size 對(duì)速度的影響
?client_batch_size 是指每一次客戶端調(diào)用 encode() 時(shí)所傳給服務(wù)器 List 的大小。出于性能考慮,請(qǐng)盡可能每次傳入較多的句子而非一次只傳一個(gè)。比如,使用下列方法調(diào)用:
bc?=?BertClient()
my_sentences?=?[s?for?s?in?my_corpus.iter()]
#?doing?encoding?in?one-shot
vec?=?bc.encode(my_sentences)
而不要使用:
vec?=?[]
for?s?in?my_corpus.iter():
????vec.append(bc.encode(s))
如果你把 bc = BertClient() 放在了循環(huán)之內(nèi),則性能會(huì)更差。當(dāng)然在一些時(shí)候,一次僅傳入一個(gè)句子無法避免,尤其是在小流量在線環(huán)境中。
?num_client 對(duì)并發(fā)性和速度的影響
?num_client 指同時(shí)連接服務(wù)的客戶端數(shù)量。當(dāng)把 bert-as-service 作為公共基礎(chǔ)設(shè)施時(shí),可能會(huì)同時(shí)有多個(gè)客戶端連接到服務(wù)獲取向量。
可以看到一個(gè)客戶端、一塊 GPU 的處理速度是每秒 381 個(gè)句子(句子的長(zhǎng)度為 40),兩個(gè)客戶端、兩個(gè) GPU 是每秒 402 個(gè),四個(gè)客戶端、四個(gè) GPU 的速度是每秒 413 個(gè)。這體現(xiàn)了 bert-as-service 良好的伸縮性:當(dāng) GPU 的數(shù)量增多時(shí),服務(wù)對(duì)每個(gè)客戶端請(qǐng)求的處理速度保持穩(wěn)定甚至略有增高(因?yàn)榭障稌r(shí)刻被更有效地利用)。
其它常見問題列表和詳細(xì)指南
參見:
https://github.com/hanxiao/bert-as-service
點(diǎn)擊以下標(biāo)題查看更多論文解讀:?
自動(dòng)機(jī)器學(xué)習(xí)(AutoML)最新綜述
自然語言處理中的語言模型預(yù)訓(xùn)練方法
從傅里葉分析角度解讀深度學(xué)習(xí)的泛化能力
深度解讀DeepMind新作:史上最強(qiáng)GAN圖像生成器
GraphWave:一種全新的無監(jiān)督網(wǎng)絡(luò)嵌入方法
這16篇最新論文,幫你輕松積攢知識(shí)點(diǎn)
TensorSpace:超酷炫3D神經(jīng)網(wǎng)絡(luò)可視化框架
#投 稿 通 道#
?讓你的論文被更多人看到?
如何才能讓更多的優(yōu)質(zhì)內(nèi)容以更短路徑到達(dá)讀者群體,縮短讀者尋找優(yōu)質(zhì)內(nèi)容的成本呢? 答案就是:你不認(rèn)識(shí)的人。
總有一些你不認(rèn)識(shí)的人,知道你想知道的東西。PaperWeekly 或許可以成為一座橋梁,促使不同背景、不同方向的學(xué)者和學(xué)術(shù)靈感相互碰撞,迸發(fā)出更多的可能性。?
PaperWeekly 鼓勵(lì)高校實(shí)驗(yàn)室或個(gè)人,在我們的平臺(tái)上分享各類優(yōu)質(zhì)內(nèi)容,可以是最新論文解讀,也可以是學(xué)習(xí)心得或技術(shù)干貨。我們的目的只有一個(gè),讓知識(shí)真正流動(dòng)起來。
??來稿標(biāo)準(zhǔn):
? 稿件確系個(gè)人原創(chuàng)作品,來稿需注明作者個(gè)人信息(姓名+學(xué)校/工作單位+學(xué)歷/職位+研究方向)?
? 如果文章并非首發(fā),請(qǐng)?jiān)谕陡鍟r(shí)提醒并附上所有已發(fā)布鏈接?
? PaperWeekly 默認(rèn)每篇文章都是首發(fā),均會(huì)添加“原創(chuàng)”標(biāo)志
? 投稿郵箱:
? 投稿郵箱:hr@paperweekly.site?
? 所有文章配圖,請(qǐng)單獨(dú)在附件中發(fā)送?
? 請(qǐng)留下即時(shí)聯(lián)系方式(微信或手機(jī)),以便我們?cè)诰庉嫲l(fā)布時(shí)和作者溝通
?
現(xiàn)在,在「知乎」也能找到我們了
進(jìn)入知乎首頁搜索「PaperWeekly」
點(diǎn)擊「關(guān)注」訂閱我們的專欄吧
關(guān)于PaperWeekly
PaperWeekly 是一個(gè)推薦、解讀、討論、報(bào)道人工智能前沿論文成果的學(xué)術(shù)平臺(tái)。如果你研究或從事 AI 領(lǐng)域,歡迎在公眾號(hào)后臺(tái)點(diǎn)擊「交流群」,小助手將把你帶入 PaperWeekly 的交流群里。
▽ 點(diǎn)擊 |?閱讀原文?| 獲取最新論文推薦
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的两行代码玩转 Google BERT 句向量词向量的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不用L约束又不会梯度消失的GAN,了解一
- 下一篇: EMNLP2018论文解读 | 利用篇章