日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

金融NLP需求落地实践总结——使用T5-Pegasus做一句话摘要

發(fā)布時間:2024/1/18 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 金融NLP需求落地实践总结——使用T5-Pegasus做一句话摘要 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

收起

T5基本原理及實現(xiàn)細節(jié)

relative position bias

layer normalization的改動

參數(shù)初始化以及dense layer中的bias去除

T5.1.1優(yōu)化了哪些內容

GEGLU替換Relu

T5-PEGASUS基本原理及tf-serving部署

tf-serving部署

keras-model轉tf-serving-pb格式

使用tf-serving部署T5-Pegasus的encoder和decoder

高效GRPC調用tf-serving服務生成文本

client代碼編寫注意點

模型以外的一些優(yōu)化

小結

最近半年沒有發(fā)文,原因是最近接的落地需求有點多,光顧著搬磚了。不過,在搬磚的過程中,也積累了一些新的NLP落地經(jīng)驗。之前我介紹過一些NLP在金融場景的落地實踐,這些實踐都屬于NLU(自然語言理解)領域。而在NLP中,自然語言生成(以下簡稱NLG)是另一個非常重要的研究領域。然而在金融領域,NLG的應用一直難以推廣,這其中有很多原因,例如構建高質量、大規(guī)模的平行訓練語料成本高、難度大;生成的文本質量不穩(wěn)定,會出現(xiàn)重復、不符合邏輯語法的情況;生成的文本無法使用客觀多樣可解釋的評價方式來評判質量;模型部署存在一定的復雜度。當然,要一次性解決所有問題是不太現(xiàn)實的,我們只能在不斷地的研究和實踐中一步一步解決上述問題。

今天,我將基于NLG中一個比較經(jīng)典的任務——生成式文本摘要,來分享我們在指定的金融違約新聞上做一句話摘要的落地小結,希望對同行有一定的啟發(fā)作用。我們使用的模型是T5-pegasus,來源于追一科技發(fā)布的模型技術,具體技術博文可參考:

T5 PEGASUS:開源一個中文生成式預訓練模型?spaces.ac.cn/archives/8209正在上傳…重新上傳取消

開源項目地址可參考:

GitHub - ZhuiyiTechnology/t5-pegasus: 中文生成式預訓練模型?github.com/ZhuiyiTechnology/t5-pegasus正在上傳…重新上傳取消

本文主要從以下幾點來介紹:

1、T5模型原理簡單介紹以及實現(xiàn)細節(jié)的一些注意點分享。

2、T5.1.1相比T5的一些優(yōu)化點介紹。

3、T5-Pegasus原理簡單介紹以及tf-serving部署實踐分享。

4、在模型之外,提升文本生成的注意點分享。

對一些基礎原理已經(jīng)比較熟悉的同學可以直接跳至感興趣的章節(jié)閱讀。

T5基本原理及實現(xiàn)細節(jié)

T5全稱是Text-to-Text Transfer Transformer,來源于google的論文:

https://arxiv.org/pdf/1910.10683.pdf?arxiv.org/pdf/1910.10683.pdf

從名字就可以看出來,它由兩大基本元素構成:

1、“Text-to-Text Transfer“部分。它的本質實際上就是把不同的NLP任務都通過某種方式轉化成一個文本生成的任務。最近比較熱門的prompt-based finetuning應用的技術思想與之有一定的相似性,但大家不要將兩者混淆。prompt-based方法提供了一種將預訓練模型遷移到下游任務的新方法,充分利用了預訓練時使用MLM學到的知識,將下游任務轉化為MLM任務,使得finetune階段和預訓練保持一致,從而更高效地利用預訓練模型學習到的知識。而T5則是認為萬物皆可文本生成,只不過不同的任務中輸入和輸出的平行語料形式不同而已,例如:情感分析任務中,輸入是待分析的文本,輸出則是代表不同情感的標志詞;機器翻譯和文本摘要都是文本生成的經(jīng)典任務,它們也可以放在一起進行訓練,只要在輸入的時候標識當前的任務名稱(或者任務提示)就能進行區(qū)分。具體轉換規(guī)則見論文中的截圖:

由于任務提示也是一段自然文本,因此模型在預訓練的時候能夠理解當前的任務特點。也因為T5在預訓練時是以文本生成任務為主,因此它天生可以用來做翻譯、摘要、文本復述等NLG任務。另外,在預訓練中,T5還借鑒了BERT的MLM思想以及span-bert的span mask思想,引入了corrupt span的思想,論文設計了很多類型的無監(jiān)督任務,最終通過實驗發(fā)現(xiàn)這樣設計訓練任務效果最好:

對于連續(xù)的span進行mask,一個span使用一個mask替換,對于該樣本,我們直接預測span中的詞,同時預測的target文本中,不同span的開頭會使用source文本中對應位置的mask來標識,具體如下圖中的紅框所示:

當然,T5的預訓練任務還有很多設置,不過因為我們基本上不會去預訓練它,因此我這邊就不詳細描述了。

2、“Transformer“部分。T5使用的基本模型還是Transformer,這塊應該不用過多介紹。T5一開始設計了三種模型架構,分別是傳統(tǒng)的seq2seq架構、只有decoder的類GPT架構以及引入prefix的LM架構(類似微軟的UniLM)。最終通過實驗,驗證了seq2seq架構的效果最好。T5的模型架構是比較簡單明了的,但是在具體實現(xiàn)過程中有很多細節(jié)需要注意:

relative position bias

在T5的transformer中,替換了原來的絕對位置編碼,使用了相對位置編碼,對attention中輸入的key和query計算兩者序列的相對位置的offset,并引入embedding計算,最終將其作為一個attention bias應用在計算attention score之后,softmax之前。相對位置編碼相比于絕對位置編碼,更能捕捉較長序列中字符之間的位置關聯(lián)信息。另外,在代碼實現(xiàn)的時候,原版的代碼引入了bucket的思想,對相對位置過于遠的情況進行了特殊處理,將大于max_distance的相對位置offset映射到[0,bucket_num)內,下面是原版代碼供大家參考:

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 ret

layer normalization的改動

相對于原版的layer normalization,T5里面的layernorm在實現(xiàn)上有一定的小改動:

1、去掉了layernorm中的bias以及center

2、將layernorm的計算放在了殘差計算的外側。

從實驗上來看,這兩者改動對最后的效果是正向的。至于原因,前一個改動在蘇神的博文中有一些推測解釋,個人認為比較符合實際,即layernorm中的center類似于bias信息,在預訓練的時候bias信息會存儲一些先驗的信息,這些先驗信息反而會影響模型的遷移學習能力。具體參考:

淺談Transformer的初始化、參數(shù)化與標準化 - 科學空間|Scientific Spaces

具體的代碼實現(xiàn)可以參考如下版本,紅框中內容即判斷是否考慮減去input的center:

參數(shù)初始化以及dense layer中的bias去除

除了layer norm中的bias去除了,其他全連接層的bias都在T5中被去除了,這個原因與上述提到的類似。另外,T5中對于全連接層中的權重參數(shù)初始化也要一定的講究。具體的原因同樣可以在蘇神的博客中找到其分析:

淺談Transformer的初始化、參數(shù)化與標準化 - 科學空間|Scientific Spaces?spaces.ac.cn/archives/8620#%E7%9B%B4%E6%8E%A5%E6%A0%87%E5%87%86%E5%8C%96

簡單來說,就是讓權重參數(shù)能夠盡量以標準差初始化,同時維持二階矩的穩(wěn)定,讓模型在訓練的時候能夠更加穩(wěn)定。T5的做法就是在正態(tài)分布初始化的時候,將標準差stddev除以??

?,d表示當前的hidden_size。這套操作與bert在attention計算時,除以的目的是類似的。而在T5中,attention計算的時候是沒有除以做scaling的操作的。?

T5.1.1優(yōu)化了哪些內容

在T5提出以后,google針對T5的結構做了一些優(yōu)化改動,提出了T5.1.1,這個版本并沒有專門發(fā)論文介紹,因此了解的人可能不多,實際上,T5的github中也列出了T5.1.1包含的優(yōu)化點:

紅框是針對模型架構優(yōu)化的一些點,其中T5.1.1取消了input embedding和最終預測詞的classifier的embedding參數(shù)共享,在分類層的時候,隨機初始化了新的embedding權重單獨學習。另外,在預訓練的過程中,將dropout都關閉了,原因可能是通過T5的實驗,發(fā)現(xiàn)T5的學習能力還未達到飽和,因此不需要使用dropout來避免過擬合。最后,T5.1.1在ff層中使用了GEGLU代理了Relu,這塊要重點提一下。

GEGLU替換Relu

GEGLU 其實可以稱為Gated Gelu,來自于論文

https://arxiv.org/pdf/2002.05202.pdf?arxiv.org/pdf/2002.05202.pdf

具體計算公式如下:

其中,W和V為kernel的參數(shù),b和c為bias。當然,在T5中bias是都去掉的,因此最終的GEGLU應當是這樣的:

這篇文章超級短,感覺都不像一篇論文,更像一個實驗報告。簡單來說,就是針對一些激活函數(shù),引入了gate機制,并針對不同的激活函數(shù),做了實驗對比。最終在T5中,發(fā)現(xiàn)gated Gelu的效果最好,至于原因,論文并沒有給出。文章最后的conclusion也比較搞笑,貼出來給大家看看。

(divine benevolence 我查了詞典是神的仁義,各位可以體會一下。。。)

T5-PEGASUS基本原理及tf-serving部署

T5-PEGASUS來自于追一科技以及蘇神的研究工作,主體模型還是基于T5.1.1。但是在預訓練時,設計了專門針對于中文文本摘要的訓練任務,具體的原理我就不贅述了,可以參考文章開頭的引用,我這里簡單羅列一下核心要素點:

1、tokenizer的優(yōu)化。模型主要基于的還是Bert的tokenizer,但是在詞表中加入了jieba分詞之后的前20萬個詞(在語料中事先統(tǒng)計得到)。在具體分詞時,如果碰到詞表中的jieba詞,則直接將該詞分出來,若沒有匹配到,則按照原來的中文tokenizer方式來做分詞。這樣做的好處是在能夠充分利用詞級別的信息,尤其是在做NLG任務時,詞級別的生成質量會比字符級別要好一點。

2、借鑒了PEGASUS的思想,PEGASUS來源于另外一篇針對文本摘要做預訓練的論文:

https://arxiv.org/abs/1912.08777?arxiv.org/abs/1912.08777

其思想為將mask的級別拓展到句子,即對于一篇文章,通過一些策略mask掉一些句子,然后用剩余的句子來預測被mask的句子的內容。T5-PEGASUS借鑒了類似的思想,區(qū)別在于它設計了一個新的預訓練樣本構建方式,針對一篇文檔,通過一種搜索策略,選擇了一定數(shù)量的target句子,并用剩余的句子作為source句子,做seq2seq任務。

T5-PEGASUS的效果還是令人欣喜的,尤其是在小樣本的情況。我們文本摘要任務的實際標注數(shù)據(jù)大概在500左右,我們將該模型與GPT-2的中文版進行實驗對比。以肉眼看,兩者生成的文本在通順度和內容相關度上都差不多,但是T5-PEGASUS在rouge-1、rouge-2、rouge-l以及BLEU-4上都比GPT-2更好,所有指標基本高1-2個百分點。

tf-serving部署

既然T5-PEGASUS的效果不錯,那么接下來就要把模型應用在實際的工程中。最簡單的應用方式就是將keras和bert4keras的所有依賴環(huán)境都打包到鏡像中,在啟動服務的時候就將模型加載到內存中,以后每次調用模型進行inference都是從內存中加載模型。這樣做除了第一次啟動服務加載模型比較耗時外,其他時間調用模型進行生成都不會花費太長時間。

當然,這個生成時間不會太長指的是在有GPU的環(huán)境下,但實際上我們線上服務很難有GPU資源供使用,因此必須在純CPU的環(huán)境下部署服務。這個時候,直接用keras調用模型進行生成的時間成本就比較高了。我實際進行了驗證,輸入一篇256個字符的文本,目標是生成一段最大長度為40的摘要文本,在CPU環(huán)境下需要花費30-40秒的時間,這個顯然難以接受,因此需要使用更高效的模型部署方式來應用模型。之前,我們有對文本分類任務的模型應用過tf-serving進行部署,最終的性能提升也是比較可觀的。最終,我決定還是使用tf-serving來部署T5-PEGASUS。

要成功使用tf-serving來部署T5-PEGASUS,需要解決幾個問題:

1、模型訓練代碼基于keras,并非直接使用tensorFlow,因此需要將keras訓練保存的模型轉化成適配tf-serving的格式。

2、T5-PEGASUS本質上是一個seq2seq模型,包含encoder和decoder,兩個模塊都是一個獨立的keras的model,如何將其應用到tf-serving上也是需要考慮的問題。

下面針對上述兩個問題,簡單介紹一下我們如何使用tf-serving來部署T5-PEGASUS。

keras-model轉tf-serving-pb格式

這部分主要是講keras保存的模型文件轉化為tf-serving支持的pb格式,一個標準的tf-serving-pb格式應當如下圖所示:

除了已經(jīng)freeze的pb模型文件之外,還要將meta graph信息以及variable權重參數(shù)的數(shù)據(jù)放在對應的variables目錄中。還需要指定模型的版本作為模型目錄(上圖中的1581428796)。

為了得到上述格式的模型文件,我們最終需要做如下的轉換操作。

首先,我們要加載訓練好的keras的model,并利用tensorFlow中的api將模型計算圖中的所有變量參數(shù)都freeze,并保存為靜止的pb文件。此時這個文件還不符合tf-serving的要求,還需要將靜止的pb文件轉化為tf-serving支持的格式,之后就可以調用tensorFlow中tf.saved_model.builder.SavedModelBuilder對象的add_meta_graph_and_variables方法,將tf-serving需要的meta graph信息和variables信息進行保存。具體的代碼可以參考這個博客:

如何將keras訓練好的模型轉換成tensorflow的.pb的文件并在TensorFlow serving環(huán)境調用?blog.csdn.net/mouxiaoqiu/article/details/81220222

有的同學可能會說keras以及tf2.0不是可以直接使用api將h5模型轉化為pb模型嗎?正如這個GitHub的issue所述:

https://github.com/ZhuiyiTechnology/pretrained-models/issues/5?github.com/ZhuiyiTechnology/pretrained-models/issues/5

里面貼上了如何將simBert轉化為tfserving-pb的api。不過使用相同做法轉化T5-pegasus會報如下類似錯誤

keras can’t pickle _thread.rlock

經(jīng)過一段時間的研究和debug,我發(fā)現(xiàn)是由于T5-PEGASUS的decoder中使用了lambda layer,上述api無法序列化一個lambda layer,具體代碼如下圖所示:

該代碼位于final_layer之中,應用在classifier layer之前。由于T5里面,會將分類層中定義的權重output embedding與input embedding中的權重參數(shù)相關聯(lián)(并非share參數(shù),而是統(tǒng)一用一個詞表),因此在分類層之前需要對decoder的output做rescaling。

這塊rescaling的原因我感覺還是為了保持模型在訓練中的穩(wěn)定,不過我在finetune階段把這塊計算去掉了,最后訓練也收斂了,且生成的文本效果并未變差。因此rescaling應該是對預訓練過程比較重要的計算。如果其他同學對這塊有自己的見解,歡迎評論。

另外,我們嘗試單獨轉化encoder是成功的,這也從側面證明了是由于decoder的存在導致不能使用上述方法來轉換。

使用tf-serving部署T5-Pegasus的encoder和decoder

我們之前對文本分類使用tf-serving進行部署的時候,通常只會封裝一個模型、一個接口,因為文本分類模型通常只會有一個輸入和一個輸出。但是對于seq2seq模型來說,包含encoder和decoder兩個子模塊,兩個子模塊的輸入和輸出都不相同,且decoder還會依賴于encoder的輸出,因此有必要將兩個子模塊分離出來,各自單獨封裝成一個獨立接口。

對于encoder來說,其輸入是source文本,輸出則是編碼了source文本語義信息的模型輸出。其簽名定義可以用如下代碼表示:

其中,需要根據(jù)graph中相應tensor的name找到input和output對應的tensor

對于decoder來說,其輸入包含了encoder輸出的source文本語義信息輸出以及前t-1個timestep已經(jīng)生成的文本(若是起始位置,則會輸入一個起始標志符表示開始生成文本)。其簽名定義可以用如下代碼表示:

高效GRPC調用tf-serving服務生成文本

通過上面的流程,我們已經(jīng)生成了適配tf-serving的pb模型,可以使用docker來啟動模型服務了,這里需要注意一點就是tf-serving的鏡像版本最好使用nightly版本,使用其他版本或多或少都會遇到一些版本問題。

最后一步,我們需要編寫代碼調用tf-serving的模型服務。tf-serving支持http協(xié)議的restful api調用以及GRPC的client-server調用。http協(xié)議比較容易實現(xiàn),但是在數(shù)據(jù)傳輸?shù)男噬厦孢€是不如GRPC協(xié)議的,因此我一般比較推薦使用GRPC協(xié)議,能夠獲得更好的性能。要使用GRPC協(xié)議就需要編寫對應的client代碼,這塊可以參考很多博客的介紹,我推薦這個博文:

Improve Tensorflow Performance by 70% | Mux blog?mux.com/blog/tuning-performance-of-tensorflow-serving-pipeline/正在上傳…重新上傳取消

可能需要用科學上網(wǎng)才能訪問。它在博文里面介紹了很多能夠提升tf-serving服務調用性能的優(yōu)化方法,包括對tf-serving進行適配物理硬件的編譯、設置一些tf-serving的啟動參數(shù)等等。它還介紹了如何從client端來進一步提升inference性能的方法,簡單來說就是client端使用的tensorFlow prediction api基本上都視作一個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端會加載所有tensorFlow和tensorflow_serving庫,這個過程會帶來很大的時延,因此我們可以預先將prediction所需要的依賴庫抽出來,然后在代碼中只加載這些庫,從而大大提升client端的效率。具體做法就是將上述的proto文件使用grpcio.tools.protoc接口將proto轉化為python實現(xiàn),接下來我們就可以直接import這些轉化后的庫。

client代碼編寫注意點

最后一步就是編寫client代碼,調用tf-serving來生成文本了。T5-PEGASUS基于seq2seq架構,最后的文本生成采用beam-search方法,它的生成過程是step-by-step的。每個step都會依賴前面歷史step的生成結果。大家可以參考這個issue里面的方法,它采用的是http協(xié)議訪問tf-serving,我們只需要將remote_call中調用tf-serving的方法轉化為client風格的調用就可以了:

讓bert4keras使用Tensorflow serving調用模型 · Issue #194 · bojone/bert4keras?github.com/bojone/bert4keras/issues/194正在上傳…重新上傳取消

詳細的代碼我就不貼出來了,這里主要提兩點編寫client代碼需要注意的問題:

1、創(chuàng)建grpc通道的時候(grpc.insecure_channel),需要指定grpc的max_send_message_length以及max_receive_message_length。因為T5-PEGASUS的encoder-output的張量還是挺大的,默認的grpc最大傳輸消息長度似乎只有4 MB,如果使用默認的長度限制,會報錯,顯示傳輸消息長度大于最大限制。因此,需要設置上面兩個參數(shù),不能設置太大,也不能設置太小。

2、調用decoder的時候,需要指定decoder_input的shape。這里要注意每個step的decoder_input的序列長度都會不同,因此需要動態(tài)獲取其shape,之前沒注意,用了一個常數(shù)值填充了代表序列長度的那個維度,導致最后生成的文本幾乎都是相同的字符。

綜上,通過tf-serving的部署以及一系列性能優(yōu)化,我們在實際的模型部署應用時,將文本生成的時間從一開始的30多秒縮減到了5秒左右,對于當前場景基本可用。

模型以外的一些優(yōu)化

之前已經(jīng)提到,T5-Pegasus的文本生成效果還是比較可觀的,不過經(jīng)過業(yè)務老師的一些質檢,也發(fā)現(xiàn)了很多小問題,這些問題有的能夠通過增加相應的訓練樣本來解決,有些則需要進行一些后處理。

例如下面這段文本:

“19鳳凰機場cp001”尋求展期,3月18日召開持有人會議

業(yè)務老師要求債券的名字盡可能還原原始的描述,包括英文字符的大小寫。這個債券名字中的cp應該是大寫的。但是T5-Pegasus中,對于大小寫是不敏感的。我嘗試過用大小寫敏感來finetune,但是效果會變壞,原因應該是在預訓練的時候模型是以大小寫不敏感的規(guī)則來學習的,因此在finetune時需要與其保持一致,否則就需要自己做預訓練。在沒有條件預訓練的情況下,我們可以針對性得做一些后處理。

具體來說可以通過引入債券名字識別的服務,將債券名字從原文中提取出來,并與摘要中的債券名字做比對,若兩個字符串只有英文字符不同,且是大小寫不同,則直接用原文抽取出來的債券名字替換摘要中的名字。

從上述問題也可以看出模型并不能handle一切,此時就需要算法工程師對相應的bad case進行分析,并引入其他的模塊來解決問題,另外也需要跟質檢人員和業(yè)務老師保持緊密溝通,隨時跟進需求。

小結

本文主要分享了我們在如何將T5-Pegasus應用在生成式摘要的任務當中。本文除了介紹T5-Pegasus的基本原理之外,也詳細介紹了如何將seq2seq模型部署并調用進行文本生成的過程。從這次實踐中,我們更加體會到了算法工程師除了研究算法模型外,還需要熟悉模型的實際應用以及相關的技術流程,只有這樣才能更好得發(fā)揮算法模型的能力。

總結

以上是生活随笔為你收集整理的金融NLP需求落地实践总结——使用T5-Pegasus做一句话摘要的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。