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