金融NLP需求落地实践总结——使用T5-Pegasus做一句话摘要
目錄
收起
T5基本原理及實(shí)現(xiàn)細(xì)節(jié)
relative position bias
layer normalization的改動(dòng)
參數(shù)初始化以及dense layer中的bias去除
T5.1.1優(yōu)化了哪些內(nèi)容
GEGLU替換Relu
T5-PEGASUS基本原理及tf-serving部署
tf-serving部署
keras-model轉(zhuǎn)tf-serving-pb格式
使用tf-serving部署T5-Pegasus的encoder和decoder
高效GRPC調(diào)用tf-serving服務(wù)生成文本
client代碼編寫(xiě)注意點(diǎn)
模型以外的一些優(yōu)化
小結(jié)
最近半年沒(méi)有發(fā)文,原因是最近接的落地需求有點(diǎn)多,光顧著搬磚了。不過(guò),在搬磚的過(guò)程中,也積累了一些新的NLP落地經(jīng)驗(yàn)。之前我介紹過(guò)一些NLP在金融場(chǎng)景的落地實(shí)踐,這些實(shí)踐都屬于NLU(自然語(yǔ)言理解)領(lǐng)域。而在NLP中,自然語(yǔ)言生成(以下簡(jiǎn)稱(chēng)NLG)是另一個(gè)非常重要的研究領(lǐng)域。然而在金融領(lǐng)域,NLG的應(yīng)用一直難以推廣,這其中有很多原因,例如構(gòu)建高質(zhì)量、大規(guī)模的平行訓(xùn)練語(yǔ)料成本高、難度大;生成的文本質(zhì)量不穩(wěn)定,會(huì)出現(xiàn)重復(fù)、不符合邏輯語(yǔ)法的情況;生成的文本無(wú)法使用客觀多樣可解釋的評(píng)價(jià)方式來(lái)評(píng)判質(zhì)量;模型部署存在一定的復(fù)雜度。當(dāng)然,要一次性解決所有問(wèn)題是不太現(xiàn)實(shí)的,我們只能在不斷地的研究和實(shí)踐中一步一步解決上述問(wèn)題。
今天,我將基于NLG中一個(gè)比較經(jīng)典的任務(wù)——生成式文本摘要,來(lái)分享我們?cè)谥付ǖ慕鹑谶`約新聞上做一句話摘要的落地小結(jié),希望對(duì)同行有一定的啟發(fā)作用。我們使用的模型是T5-pegasus,來(lái)源于追一科技發(fā)布的模型技術(shù),具體技術(shù)博文可參考:
T5 PEGASUS:開(kāi)源一個(gè)中文生成式預(yù)訓(xùn)練模型?spaces.ac.cn/archives/8209正在上傳…重新上傳取消
開(kāi)源項(xiàng)目地址可參考:
GitHub - ZhuiyiTechnology/t5-pegasus: 中文生成式預(yù)訓(xùn)練模型?github.com/ZhuiyiTechnology/t5-pegasus正在上傳…重新上傳取消
本文主要從以下幾點(diǎn)來(lái)介紹:
1、T5模型原理簡(jiǎn)單介紹以及實(shí)現(xiàn)細(xì)節(jié)的一些注意點(diǎn)分享。
2、T5.1.1相比T5的一些優(yōu)化點(diǎn)介紹。
3、T5-Pegasus原理簡(jiǎn)單介紹以及tf-serving部署實(shí)踐分享。
4、在模型之外,提升文本生成的注意點(diǎn)分享。
對(duì)一些基礎(chǔ)原理已經(jīng)比較熟悉的同學(xué)可以直接跳至感興趣的章節(jié)閱讀。
T5基本原理及實(shí)現(xiàn)細(xì)節(jié)
T5全稱(chēng)是Text-to-Text Transfer Transformer,來(lái)源于google的論文:
https://arxiv.org/pdf/1910.10683.pdf?arxiv.org/pdf/1910.10683.pdf
從名字就可以看出來(lái),它由兩大基本元素構(gòu)成:
1、“Text-to-Text Transfer“部分。它的本質(zhì)實(shí)際上就是把不同的NLP任務(wù)都通過(guò)某種方式轉(zhuǎn)化成一個(gè)文本生成的任務(wù)。最近比較熱門(mén)的prompt-based finetuning應(yīng)用的技術(shù)思想與之有一定的相似性,但大家不要將兩者混淆。prompt-based方法提供了一種將預(yù)訓(xùn)練模型遷移到下游任務(wù)的新方法,充分利用了預(yù)訓(xùn)練時(shí)使用MLM學(xué)到的知識(shí),將下游任務(wù)轉(zhuǎn)化為MLM任務(wù),使得finetune階段和預(yù)訓(xùn)練保持一致,從而更高效地利用預(yù)訓(xùn)練模型學(xué)習(xí)到的知識(shí)。而T5則是認(rèn)為萬(wàn)物皆可文本生成,只不過(guò)不同的任務(wù)中輸入和輸出的平行語(yǔ)料形式不同而已,例如:情感分析任務(wù)中,輸入是待分析的文本,輸出則是代表不同情感的標(biāo)志詞;機(jī)器翻譯和文本摘要都是文本生成的經(jīng)典任務(wù),它們也可以放在一起進(jìn)行訓(xùn)練,只要在輸入的時(shí)候標(biāo)識(shí)當(dāng)前的任務(wù)名稱(chēng)(或者任務(wù)提示)就能進(jìn)行區(qū)分。具體轉(zhuǎn)換規(guī)則見(jiàn)論文中的截圖:
由于任務(wù)提示也是一段自然文本,因此模型在預(yù)訓(xùn)練的時(shí)候能夠理解當(dāng)前的任務(wù)特點(diǎn)。也因?yàn)門(mén)5在預(yù)訓(xùn)練時(shí)是以文本生成任務(wù)為主,因此它天生可以用來(lái)做翻譯、摘要、文本復(fù)述等NLG任務(wù)。另外,在預(yù)訓(xùn)練中,T5還借鑒了BERT的MLM思想以及span-bert的span mask思想,引入了corrupt span的思想,論文設(shè)計(jì)了很多類(lèi)型的無(wú)監(jiān)督任務(wù),最終通過(guò)實(shí)驗(yàn)發(fā)現(xiàn)這樣設(shè)計(jì)訓(xùn)練任務(wù)效果最好:
對(duì)于連續(xù)的span進(jìn)行mask,一個(gè)span使用一個(gè)mask替換,對(duì)于該樣本,我們直接預(yù)測(cè)span中的詞,同時(shí)預(yù)測(cè)的target文本中,不同span的開(kāi)頭會(huì)使用source文本中對(duì)應(yīng)位置的mask來(lái)標(biāo)識(shí),具體如下圖中的紅框所示:
當(dāng)然,T5的預(yù)訓(xùn)練任務(wù)還有很多設(shè)置,不過(guò)因?yàn)槲覀兓旧喜粫?huì)去預(yù)訓(xùn)練它,因此我這邊就不詳細(xì)描述了。
2、“Transformer“部分。T5使用的基本模型還是Transformer,這塊應(yīng)該不用過(guò)多介紹。T5一開(kāi)始設(shè)計(jì)了三種模型架構(gòu),分別是傳統(tǒng)的seq2seq架構(gòu)、只有decoder的類(lèi)GPT架構(gòu)以及引入prefix的LM架構(gòu)(類(lèi)似微軟的UniLM)。最終通過(guò)實(shí)驗(yàn),驗(yàn)證了seq2seq架構(gòu)的效果最好。T5的模型架構(gòu)是比較簡(jiǎn)單明了的,但是在具體實(shí)現(xiàn)過(guò)程中有很多細(xì)節(jié)需要注意:
relative position bias
在T5的transformer中,替換了原來(lái)的絕對(duì)位置編碼,使用了相對(duì)位置編碼,對(duì)attention中輸入的key和query計(jì)算兩者序列的相對(duì)位置的offset,并引入embedding計(jì)算,最終將其作為一個(gè)attention bias應(yīng)用在計(jì)算attention score之后,softmax之前。相對(duì)位置編碼相比于絕對(duì)位置編碼,更能捕捉較長(zhǎng)序列中字符之間的位置關(guān)聯(lián)信息。另外,在代碼實(shí)現(xiàn)的時(shí)候,原版的代碼引入了bucket的思想,對(duì)相對(duì)位置過(guò)于遠(yuǎn)的情況進(jìn)行了特殊處理,將大于max_distance的相對(duì)位置offset映射到[0,bucket_num)內(nèi),下面是原版代碼供大家參考:
def relative_position_bucket(self,relative_position,bidirectional=True,num_buckets=32,max_distance=128):"""Translate relative position to a bucket number for relative attention.The relative position is defined as memory_position - query_position, i.e.the distance in tokens from the attending position to the attended-toposition. If bidirectional=False, then positive relative positions areinvalid.We use smaller buckets for small absolute relative_position and larger bucketsfor larger absolute relative_positions. All relative positions >=max_distancemap to the same bucket. All relative positions <=-max_distance map to thesame bucket. This should allow for more graceful generalization to longersequences than the model has been trained on.Args:relative_position: an int32 Tensorbidirectional: a boolean - whether the attention is bidirectionalnum_buckets: an integermax_distance: an integerReturns:a Tensor with the same shape as relative_position, containing int32values in the range [0, num_buckets)"""ret = 0n = -relative_positionif bidirectional:num_buckets //= 2ret += tf.to_int32(tf.less(n, 0)) * num_bucketsn = tf.abs(n)else:n = tf.maximum(n, 0)# now n is in the range [0, inf)max_exact = num_buckets // 2is_small = tf.less(n, max_exact)val_if_large = max_exact + tf.to_int32(tf.log(tf.to_float(n) / max_exact)/ math.log(max_distance / max_exact) * (num_buckets - max_exact))val_if_large = tf.minimum(val_if_large, num_buckets - 1)ret += tf.where(is_small, n, val_if_large)return retlayer normalization的改動(dòng)
相對(duì)于原版的layer normalization,T5里面的layernorm在實(shí)現(xiàn)上有一定的小改動(dòng):
1、去掉了layernorm中的bias以及center
2、將layernorm的計(jì)算放在了殘差計(jì)算的外側(cè)。
從實(shí)驗(yàn)上來(lái)看,這兩者改動(dòng)對(duì)最后的效果是正向的。至于原因,前一個(gè)改動(dòng)在蘇神的博文中有一些推測(cè)解釋,個(gè)人認(rèn)為比較符合實(shí)際,即layernorm中的center類(lèi)似于bias信息,在預(yù)訓(xùn)練的時(shí)候bias信息會(huì)存儲(chǔ)一些先驗(yàn)的信息,這些先驗(yàn)信息反而會(huì)影響模型的遷移學(xué)習(xí)能力。具體參考:
淺談Transformer的初始化、參數(shù)化與標(biāo)準(zhǔn)化 - 科學(xué)空間|Scientific Spaces
具體的代碼實(shí)現(xiàn)可以參考如下版本,紅框中內(nèi)容即判斷是否考慮減去input的center:
參數(shù)初始化以及dense layer中的bias去除
除了layer norm中的bias去除了,其他全連接層的bias都在T5中被去除了,這個(gè)原因與上述提到的類(lèi)似。另外,T5中對(duì)于全連接層中的權(quán)重參數(shù)初始化也要一定的講究。具體的原因同樣可以在蘇神的博客中找到其分析:
淺談Transformer的初始化、參數(shù)化與標(biāo)準(zhǔn)化 - 科學(xué)空間|Scientific Spaces?spaces.ac.cn/archives/8620#%E7%9B%B4%E6%8E%A5%E6%A0%87%E5%87%86%E5%8C%96
簡(jiǎn)單來(lái)說(shuō),就是讓權(quán)重參數(shù)能夠盡量以標(biāo)準(zhǔn)差初始化,同時(shí)維持二階矩的穩(wěn)定,讓模型在訓(xùn)練的時(shí)候能夠更加穩(wěn)定。T5的做法就是在正態(tài)分布初始化的時(shí)候,將標(biāo)準(zhǔn)差stddev除以??
?,d表示當(dāng)前的hidden_size。這套操作與bert在attention計(jì)算時(shí),除以的目的是類(lèi)似的。而在T5中,attention計(jì)算的時(shí)候是沒(méi)有除以做scaling的操作的。?
T5.1.1優(yōu)化了哪些內(nèi)容
在T5提出以后,google針對(duì)T5的結(jié)構(gòu)做了一些優(yōu)化改動(dòng),提出了T5.1.1,這個(gè)版本并沒(méi)有專(zhuān)門(mén)發(fā)論文介紹,因此了解的人可能不多,實(shí)際上,T5的github中也列出了T5.1.1包含的優(yōu)化點(diǎn):
紅框是針對(duì)模型架構(gòu)優(yōu)化的一些點(diǎn),其中T5.1.1取消了input embedding和最終預(yù)測(cè)詞的classifier的embedding參數(shù)共享,在分類(lèi)層的時(shí)候,隨機(jī)初始化了新的embedding權(quán)重單獨(dú)學(xué)習(xí)。另外,在預(yù)訓(xùn)練的過(guò)程中,將dropout都關(guān)閉了,原因可能是通過(guò)T5的實(shí)驗(yàn),發(fā)現(xiàn)T5的學(xué)習(xí)能力還未達(dá)到飽和,因此不需要使用dropout來(lái)避免過(guò)擬合。最后,T5.1.1在ff層中使用了GEGLU代理了Relu,這塊要重點(diǎn)提一下。
GEGLU替換Relu
GEGLU 其實(shí)可以稱(chēng)為Gated Gelu,來(lái)自于論文
https://arxiv.org/pdf/2002.05202.pdf?arxiv.org/pdf/2002.05202.pdf
具體計(jì)算公式如下:
其中,W和V為kernel的參數(shù),b和c為bias。當(dāng)然,在T5中bias是都去掉的,因此最終的GEGLU應(yīng)當(dāng)是這樣的:
這篇文章超級(jí)短,感覺(jué)都不像一篇論文,更像一個(gè)實(shí)驗(yàn)報(bào)告。簡(jiǎn)單來(lái)說(shuō),就是針對(duì)一些激活函數(shù),引入了gate機(jī)制,并針對(duì)不同的激活函數(shù),做了實(shí)驗(yàn)對(duì)比。最終在T5中,發(fā)現(xiàn)gated Gelu的效果最好,至于原因,論文并沒(méi)有給出。文章最后的conclusion也比較搞笑,貼出來(lái)給大家看看。
(divine benevolence 我查了詞典是神的仁義,各位可以體會(huì)一下。。。)T5-PEGASUS基本原理及tf-serving部署
T5-PEGASUS來(lái)自于追一科技以及蘇神的研究工作,主體模型還是基于T5.1.1。但是在預(yù)訓(xùn)練時(shí),設(shè)計(jì)了專(zhuān)門(mén)針對(duì)于中文文本摘要的訓(xùn)練任務(wù),具體的原理我就不贅述了,可以參考文章開(kāi)頭的引用,我這里簡(jiǎn)單羅列一下核心要素點(diǎn):
1、tokenizer的優(yōu)化。模型主要基于的還是Bert的tokenizer,但是在詞表中加入了jieba分詞之后的前20萬(wàn)個(gè)詞(在語(yǔ)料中事先統(tǒng)計(jì)得到)。在具體分詞時(shí),如果碰到詞表中的jieba詞,則直接將該詞分出來(lái),若沒(méi)有匹配到,則按照原來(lái)的中文tokenizer方式來(lái)做分詞。這樣做的好處是在能夠充分利用詞級(jí)別的信息,尤其是在做NLG任務(wù)時(shí),詞級(jí)別的生成質(zhì)量會(huì)比字符級(jí)別要好一點(diǎn)。
2、借鑒了PEGASUS的思想,PEGASUS來(lái)源于另外一篇針對(duì)文本摘要做預(yù)訓(xùn)練的論文:
https://arxiv.org/abs/1912.08777?arxiv.org/abs/1912.08777
其思想為將mask的級(jí)別拓展到句子,即對(duì)于一篇文章,通過(guò)一些策略mask掉一些句子,然后用剩余的句子來(lái)預(yù)測(cè)被mask的句子的內(nèi)容。T5-PEGASUS借鑒了類(lèi)似的思想,區(qū)別在于它設(shè)計(jì)了一個(gè)新的預(yù)訓(xùn)練樣本構(gòu)建方式,針對(duì)一篇文檔,通過(guò)一種搜索策略,選擇了一定數(shù)量的target句子,并用剩余的句子作為source句子,做seq2seq任務(wù)。
T5-PEGASUS的效果還是令人欣喜的,尤其是在小樣本的情況。我們文本摘要任務(wù)的實(shí)際標(biāo)注數(shù)據(jù)大概在500左右,我們將該模型與GPT-2的中文版進(jìn)行實(shí)驗(yàn)對(duì)比。以肉眼看,兩者生成的文本在通順度和內(nèi)容相關(guān)度上都差不多,但是T5-PEGASUS在rouge-1、rouge-2、rouge-l以及BLEU-4上都比GPT-2更好,所有指標(biāo)基本高1-2個(gè)百分點(diǎn)。
tf-serving部署
既然T5-PEGASUS的效果不錯(cuò),那么接下來(lái)就要把模型應(yīng)用在實(shí)際的工程中。最簡(jiǎn)單的應(yīng)用方式就是將keras和bert4keras的所有依賴(lài)環(huán)境都打包到鏡像中,在啟動(dòng)服務(wù)的時(shí)候就將模型加載到內(nèi)存中,以后每次調(diào)用模型進(jìn)行inference都是從內(nèi)存中加載模型。這樣做除了第一次啟動(dòng)服務(wù)加載模型比較耗時(shí)外,其他時(shí)間調(diào)用模型進(jìn)行生成都不會(huì)花費(fèi)太長(zhǎng)時(shí)間。
當(dāng)然,這個(gè)生成時(shí)間不會(huì)太長(zhǎng)指的是在有GPU的環(huán)境下,但實(shí)際上我們線上服務(wù)很難有GPU資源供使用,因此必須在純CPU的環(huán)境下部署服務(wù)。這個(gè)時(shí)候,直接用keras調(diào)用模型進(jìn)行生成的時(shí)間成本就比較高了。我實(shí)際進(jìn)行了驗(yàn)證,輸入一篇256個(gè)字符的文本,目標(biāo)是生成一段最大長(zhǎng)度為40的摘要文本,在CPU環(huán)境下需要花費(fèi)30-40秒的時(shí)間,這個(gè)顯然難以接受,因此需要使用更高效的模型部署方式來(lái)應(yīng)用模型。之前,我們有對(duì)文本分類(lèi)任務(wù)的模型應(yīng)用過(guò)tf-serving進(jìn)行部署,最終的性能提升也是比較可觀的。最終,我決定還是使用tf-serving來(lái)部署T5-PEGASUS。
要成功使用tf-serving來(lái)部署T5-PEGASUS,需要解決幾個(gè)問(wèn)題:
1、模型訓(xùn)練代碼基于keras,并非直接使用tensorFlow,因此需要將keras訓(xùn)練保存的模型轉(zhuǎn)化成適配tf-serving的格式。
2、T5-PEGASUS本質(zhì)上是一個(gè)seq2seq模型,包含encoder和decoder,兩個(gè)模塊都是一個(gè)獨(dú)立的keras的model,如何將其應(yīng)用到tf-serving上也是需要考慮的問(wèn)題。
下面針對(duì)上述兩個(gè)問(wèn)題,簡(jiǎn)單介紹一下我們?nèi)绾问褂胻f-serving來(lái)部署T5-PEGASUS。
keras-model轉(zhuǎn)tf-serving-pb格式
這部分主要是講keras保存的模型文件轉(zhuǎn)化為tf-serving支持的pb格式,一個(gè)標(biāo)準(zhǔn)的tf-serving-pb格式應(yīng)當(dāng)如下圖所示:
除了已經(jīng)freeze的pb模型文件之外,還要將meta graph信息以及variable權(quán)重參數(shù)的數(shù)據(jù)放在對(duì)應(yīng)的variables目錄中。還需要指定模型的版本作為模型目錄(上圖中的1581428796)。
為了得到上述格式的模型文件,我們最終需要做如下的轉(zhuǎn)換操作。
首先,我們要加載訓(xùn)練好的keras的model,并利用tensorFlow中的api將模型計(jì)算圖中的所有變量參數(shù)都freeze,并保存為靜止的pb文件。此時(shí)這個(gè)文件還不符合tf-serving的要求,還需要將靜止的pb文件轉(zhuǎn)化為tf-serving支持的格式,之后就可以調(diào)用tensorFlow中tf.saved_model.builder.SavedModelBuilder對(duì)象的add_meta_graph_and_variables方法,將tf-serving需要的meta graph信息和variables信息進(jìn)行保存。具體的代碼可以參考這個(gè)博客:
如何將keras訓(xùn)練好的模型轉(zhuǎn)換成tensorflow的.pb的文件并在TensorFlow serving環(huán)境調(diào)用?blog.csdn.net/mouxiaoqiu/article/details/81220222
有的同學(xué)可能會(huì)說(shuō)keras以及tf2.0不是可以直接使用api將h5模型轉(zhuǎn)化為pb模型嗎?正如這個(gè)GitHub的issue所述:
https://github.com/ZhuiyiTechnology/pretrained-models/issues/5?github.com/ZhuiyiTechnology/pretrained-models/issues/5
里面貼上了如何將simBert轉(zhuǎn)化為tfserving-pb的api。不過(guò)使用相同做法轉(zhuǎn)化T5-pegasus會(huì)報(bào)如下類(lèi)似錯(cuò)誤:
keras can’t pickle _thread.rlock經(jīng)過(guò)一段時(shí)間的研究和debug,我發(fā)現(xiàn)是由于T5-PEGASUS的decoder中使用了lambda layer,上述api無(wú)法序列化一個(gè)lambda layer,具體代碼如下圖所示:
該代碼位于final_layer之中,應(yīng)用在classifier layer之前。由于T5里面,會(huì)將分類(lèi)層中定義的權(quán)重output embedding與input embedding中的權(quán)重參數(shù)相關(guān)聯(lián)(并非share參數(shù),而是統(tǒng)一用一個(gè)詞表),因此在分類(lèi)層之前需要對(duì)decoder的output做rescaling。
這塊rescaling的原因我感覺(jué)還是為了保持模型在訓(xùn)練中的穩(wěn)定,不過(guò)我在finetune階段把這塊計(jì)算去掉了,最后訓(xùn)練也收斂了,且生成的文本效果并未變差。因此rescaling應(yīng)該是對(duì)預(yù)訓(xùn)練過(guò)程比較重要的計(jì)算。如果其他同學(xué)對(duì)這塊有自己的見(jiàn)解,歡迎評(píng)論。另外,我們嘗試單獨(dú)轉(zhuǎn)化encoder是成功的,這也從側(cè)面證明了是由于decoder的存在導(dǎo)致不能使用上述方法來(lái)轉(zhuǎn)換。
使用tf-serving部署T5-Pegasus的encoder和decoder
我們之前對(duì)文本分類(lèi)使用tf-serving進(jìn)行部署的時(shí)候,通常只會(huì)封裝一個(gè)模型、一個(gè)接口,因?yàn)槲谋痉诸?lèi)模型通常只會(huì)有一個(gè)輸入和一個(gè)輸出。但是對(duì)于seq2seq模型來(lái)說(shuō),包含encoder和decoder兩個(gè)子模塊,兩個(gè)子模塊的輸入和輸出都不相同,且decoder還會(huì)依賴(lài)于encoder的輸出,因此有必要將兩個(gè)子模塊分離出來(lái),各自單獨(dú)封裝成一個(gè)獨(dú)立接口。
對(duì)于encoder來(lái)說(shuō),其輸入是source文本,輸出則是編碼了source文本語(yǔ)義信息的模型輸出。其簽名定義可以用如下代碼表示:
其中,需要根據(jù)graph中相應(yīng)tensor的name找到input和output對(duì)應(yīng)的tensor。
對(duì)于decoder來(lái)說(shuō),其輸入包含了encoder輸出的source文本語(yǔ)義信息輸出以及前t-1個(gè)timestep已經(jīng)生成的文本(若是起始位置,則會(huì)輸入一個(gè)起始標(biāo)志符表示開(kāi)始生成文本)。其簽名定義可以用如下代碼表示:
高效GRPC調(diào)用tf-serving服務(wù)生成文本
通過(guò)上面的流程,我們已經(jīng)生成了適配tf-serving的pb模型,可以使用docker來(lái)啟動(dòng)模型服務(wù)了,這里需要注意一點(diǎn)就是tf-serving的鏡像版本最好使用nightly版本,使用其他版本或多或少都會(huì)遇到一些版本問(wèn)題。
最后一步,我們需要編寫(xiě)代碼調(diào)用tf-serving的模型服務(wù)。tf-serving支持http協(xié)議的restful api調(diào)用以及GRPC的client-server調(diào)用。http協(xié)議比較容易實(shí)現(xiàn),但是在數(shù)據(jù)傳輸?shù)男噬厦孢€是不如GRPC協(xié)議的,因此我一般比較推薦使用GRPC協(xié)議,能夠獲得更好的性能。要使用GRPC協(xié)議就需要編寫(xiě)對(duì)應(yīng)的client代碼,這塊可以參考很多博客的介紹,我推薦這個(gè)博文:
Improve Tensorflow Performance by 70% | Mux blog?mux.com/blog/tuning-performance-of-tensorflow-serving-pipeline/正在上傳…重新上傳取消
可能需要用科學(xué)上網(wǎng)才能訪問(wèn)。它在博文里面介紹了很多能夠提升tf-serving服務(wù)調(diào)用性能的優(yōu)化方法,包括對(duì)tf-serving進(jìn)行適配物理硬件的編譯、設(shè)置一些tf-serving的啟動(dòng)參數(shù)等等。它還介紹了如何從client端來(lái)進(jìn)一步提升inference性能的方法,簡(jiǎn)單來(lái)說(shuō)就是client端使用的tensorFlow prediction api基本上都視作一個(gè)protobuf 程序段,如下所示:
tensorflow/serving/tensorflow_serving/apis/model.prototensorflow_serving/apis/predict.prototensorflow_serving/apis/prediction_service.prototensorflow/tensorflow/tensorflow/core/framework/resource_handle.prototensorflow/core/framework/tensor_shape.prototensorflow/core/framework/tensor.prototensorflow/core/framework/types.proto正常情況下client端會(huì)加載所有tensorFlow和tensorflow_serving庫(kù),這個(gè)過(guò)程會(huì)帶來(lái)很大的時(shí)延,因此我們可以預(yù)先將prediction所需要的依賴(lài)庫(kù)抽出來(lái),然后在代碼中只加載這些庫(kù),從而大大提升client端的效率。具體做法就是將上述的proto文件使用grpcio.tools.protoc接口將proto轉(zhuǎn)化為python實(shí)現(xiàn),接下來(lái)我們就可以直接import這些轉(zhuǎn)化后的庫(kù)。
client代碼編寫(xiě)注意點(diǎn)
最后一步就是編寫(xiě)client代碼,調(diào)用tf-serving來(lái)生成文本了。T5-PEGASUS基于seq2seq架構(gòu),最后的文本生成采用beam-search方法,它的生成過(guò)程是step-by-step的。每個(gè)step都會(huì)依賴(lài)前面歷史step的生成結(jié)果。大家可以參考這個(gè)issue里面的方法,它采用的是http協(xié)議訪問(wèn)tf-serving,我們只需要將remote_call中調(diào)用tf-serving的方法轉(zhuǎn)化為client風(fēng)格的調(diào)用就可以了:
讓bert4keras使用Tensorflow serving調(diào)用模型 · Issue #194 · bojone/bert4keras?github.com/bojone/bert4keras/issues/194正在上傳…重新上傳取消
詳細(xì)的代碼我就不貼出來(lái)了,這里主要提兩點(diǎn)編寫(xiě)client代碼需要注意的問(wèn)題:
1、創(chuàng)建grpc通道的時(shí)候(grpc.insecure_channel),需要指定grpc的max_send_message_length以及max_receive_message_length。因?yàn)門(mén)5-PEGASUS的encoder-output的張量還是挺大的,默認(rèn)的grpc最大傳輸消息長(zhǎng)度似乎只有4 MB,如果使用默認(rèn)的長(zhǎng)度限制,會(huì)報(bào)錯(cuò),顯示傳輸消息長(zhǎng)度大于最大限制。因此,需要設(shè)置上面兩個(gè)參數(shù),不能設(shè)置太大,也不能設(shè)置太小。
2、調(diào)用decoder的時(shí)候,需要指定decoder_input的shape。這里要注意每個(gè)step的decoder_input的序列長(zhǎng)度都會(huì)不同,因此需要?jiǎng)討B(tài)獲取其shape,之前沒(méi)注意,用了一個(gè)常數(shù)值填充了代表序列長(zhǎng)度的那個(gè)維度,導(dǎo)致最后生成的文本幾乎都是相同的字符。
綜上,通過(guò)tf-serving的部署以及一系列性能優(yōu)化,我們?cè)趯?shí)際的模型部署應(yīng)用時(shí),將文本生成的時(shí)間從一開(kāi)始的30多秒縮減到了5秒左右,對(duì)于當(dāng)前場(chǎng)景基本可用。
模型以外的一些優(yōu)化
之前已經(jīng)提到,T5-Pegasus的文本生成效果還是比較可觀的,不過(guò)經(jīng)過(guò)業(yè)務(wù)老師的一些質(zhì)檢,也發(fā)現(xiàn)了很多小問(wèn)題,這些問(wèn)題有的能夠通過(guò)增加相應(yīng)的訓(xùn)練樣本來(lái)解決,有些則需要進(jìn)行一些后處理。
例如下面這段文本:
“19鳳凰機(jī)場(chǎng)cp001”尋求展期,3月18日召開(kāi)持有人會(huì)議業(yè)務(wù)老師要求債券的名字盡可能還原原始的描述,包括英文字符的大小寫(xiě)。這個(gè)債券名字中的cp應(yīng)該是大寫(xiě)的。但是T5-Pegasus中,對(duì)于大小寫(xiě)是不敏感的。我嘗試過(guò)用大小寫(xiě)敏感來(lái)finetune,但是效果會(huì)變壞,原因應(yīng)該是在預(yù)訓(xùn)練的時(shí)候模型是以大小寫(xiě)不敏感的規(guī)則來(lái)學(xué)習(xí)的,因此在finetune時(shí)需要與其保持一致,否則就需要自己做預(yù)訓(xùn)練。在沒(méi)有條件預(yù)訓(xùn)練的情況下,我們可以針對(duì)性得做一些后處理。
具體來(lái)說(shuō)可以通過(guò)引入債券名字識(shí)別的服務(wù),將債券名字從原文中提取出來(lái),并與摘要中的債券名字做比對(duì),若兩個(gè)字符串只有英文字符不同,且是大小寫(xiě)不同,則直接用原文抽取出來(lái)的債券名字替換摘要中的名字。
從上述問(wèn)題也可以看出模型并不能handle一切,此時(shí)就需要算法工程師對(duì)相應(yīng)的bad case進(jìn)行分析,并引入其他的模塊來(lái)解決問(wèn)題,另外也需要跟質(zhì)檢人員和業(yè)務(wù)老師保持緊密溝通,隨時(shí)跟進(jìn)需求。
小結(jié)
本文主要分享了我們?cè)谌绾螌5-Pegasus應(yīng)用在生成式摘要的任務(wù)當(dāng)中。本文除了介紹T5-Pegasus的基本原理之外,也詳細(xì)介紹了如何將seq2seq模型部署并調(diào)用進(jìn)行文本生成的過(guò)程。從這次實(shí)踐中,我們更加體會(huì)到了算法工程師除了研究算法模型外,還需要熟悉模型的實(shí)際應(yīng)用以及相關(guān)的技術(shù)流程,只有這樣才能更好得發(fā)揮算法模型的能力。
總結(jié)
以上是生活随笔為你收集整理的金融NLP需求落地实践总结——使用T5-Pegasus做一句话摘要的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 京东物流CEO王振辉:供应链数字化是产业
- 下一篇: simhash算法介绍-尾部添加比较经典