百度飛槳PaddlePaddle——如何利用百度Knover訓練出一個多輪對話模型

這是一個比較詳盡的Knover使用手冊python

該項目是從項目集「沒有對象就本身造」提煉總結出來的,感興趣的請參考連接的「沒有對象就本身造板塊」。這個集合主要的目的是記錄我關於Knover的使用心得,併爲之後使用這個工具的人提供一些快速入門的建議。其中不免有一些錯誤的地方,還請見諒。git

github連接:https://github.com/fiyen/PaddlePaddle-Knovergithub

下載安裝命令

## CPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

1 什麼是Knover

Knover是基於飛槳的開放域對話模型訓練工具箱。經過Knover,咱們能夠輕鬆訓練出一個開放域對話模型,並支持多種輸入格式,支持單文件和多文件讀取。同時,Knover提供了基於飛槳的優秀的優化訓練策略,加速模型的訓練。目前,Knover已經支持PLATO-2模型的訓練。
Knover官網:https://github.com/PaddlePaddle/Knoverjson

2 什麼是PLATO-2

Plato是百度推出的一個基於飛槳的多輪對話模型。該模型的最大改進在於經過引入離散隱變量實現了對話場景中多回答中的擇優,即,對於同一個問題,實現不一樣場景下的不一樣回答的選擇。最新推出的Plato-2在中英文效果上,已全面超越 Google Meena、Facebook Blender、微軟小冰等先進模型。
模型的總體框架如圖所示。該模型採用了經典的Transformer結構,經過注意力機制提升了模型針對不一樣長度對話的生成效果。隱變量z的引入,使預訓練模型依據z能夠生成多種回答,最終回答從多種回答中擇優。在訓練中,該模型採用兩階段訓練的方法。第一階段,基於表現良好的預訓練模型,訓練出一對一回答的模型;第二階段,引入評估和隱變量z,訓練出一對多回答的模型。模型的具體原理能夠參考原論文,論文地址:https://arxiv.org/abs/2006.16779 。框架

在這裏插入圖片描述

3 認識Knover

3.1 認識Knover的主要文件

對於Knover的使用,用命令行是比較方便的(固然若是有能力能夠調用sh文件)。根目錄的三個文件:train.py,test.py和save_inference_model.py是最常常用到的。從名稱也能夠看出來,train.py用來訓練,test.py用來測試,save_inference_model用來導出預測用的模型,這一個是在模型訓練完之後,部署訓練好的模型,又但願保持模型儘量縮減沒必要要的參數時用的。分佈式

1.package文件夾中存放了其自帶的試驗數據的詞集,語句切分模型(spm.model, 即sentencepiece model,這個模型用在語句的預處理上,必須給定),以及模型的細節參數(詞集大小,隱含層個數,激活函數等等,具體查看package/dialog_en/24L.json。
2.models文件夾存放了模型的各個子模塊,plato模塊也在其中
3.data文件夾存放了實驗用的小文件
4.tasks文件夾中包含了模型兩種應用任務的實現,包括「下一句語句預測」和「會話生成」。這個應用任務的選擇是必須給出的,對應參數 --tasks, 分別寫做NextSentencePredictionDialogGeneration。具體來講,DialogGeneration是訓練對話模型時用到的,而NextSentencePrediction是在訓練打分模型時用到的。這裏的具體區別後邊再講。函數

3.2 認識Konver的主要參數

--init_pretraining_params 預訓練模型所在文件夾,若是須要加載(固然須要)預訓練模型須要給出這個參數工具

--init_checkpoint 保存節點的所在文件夾,若是給出了init_checkpoint則從該文件夾初始化訓練參數(等於覆蓋了init_pretraining_params的參數),checkpoint保存了模型更多的細節,如訓練步數,當前學習率,還有模型涉及的全部訓練參數等,若是從checkpoint開始繼續訓練模型,模型會從以前中斷的狀態繼續訓練,若是不設--start_step模型會錯誤顯示當前的步數,可是內部的參數是按照正確的步數更新的。post

--max_seq_len: 最長輸入長度學習

--is_distributed: 是否進行分佈式訓練,即用多顯卡進行加速

train.py

--train_file 訓練文件地址

--valid_file 評估文件地址

--model 用到的模型名稱:Plato:plato;NSPModel:next_sentence_prediction model;UnifiedTransformer

--config_path 模型細節參數配置文件,如24L.json

--task 模型應用任務 NextSentencePredictionDialogGeneration

--vocab_path 詞集路徑

--spm_model_file sentencepiece model文件的路徑

--num_epochs 訓練週期數

--log_steps 輸出訓練詳情的間隔步數

--validation_steps 評價間隔步數

--save_steps 保存間隔步數

--start_step: 訓練開始步長,用於中斷後繼續訓練,不設置也不會影響訓練,可是會形成輸出的步數是錯的

--batch_size: 訓練中的批數據大小

--lr --warmup_steps weight_decay: 學習率相關選項

infer.py

--infer_file 須要推斷的文件

--output_name 須要保存的對象,responsedata_idscore

--model 用到的模型名稱:Plato:plato;NSPModel:next_sentence_prediction model;UnifiedTransformer

--config_path 模型細節參數配置文件,如24L.json

--task 模型應用任務 NextSentencePredictionDialogGeneration
--vocab_path 詞集路徑

--spm_model_file sentencepiece model文件的路徑

3.3 瞭解對話模型的訓練

3.3.1 通常模型的訓練

第一步:在進行訓練以前,須要提早準備好幾個文件:詳列模型參數的.json文件,如config文件夾下的24L.json文件;分詞工具的預訓練模型,如spm.model文件;以及分詞後造成的詞表文件,如vocab.txt。

第二步:準備數據。把本身準備的訓練數據轉換成合適的格式,存入txt文件,供訓練使用。

第三步:調用train.py進行訓練,模型選擇UnifiedTransformer,任務選擇DialogGeneration

第四步:訓練完成後,調用save_inference_model.py將預測模型導出

通過以上四步,模型就訓練好了。固然這個過程須要巨量的訓練集作支撐才能訓練出好的模型。

3.3.2 Plato-2模型的訓練

在上述四步完成後進行。前兩步與上述過程類似,在訓練出UnifiedTransformer模型後,按照如下步驟進行訓練:

第三步:調用train.py進行訓練,模型選擇Plato,任務選擇DialogGeneration,而且--init_pretraining_params選擇以前訓練好的UnfiedTransformer模型(若是未進行上述第四步,則導出的模型能夠用--init_checkpoint指定)

第四步:訓練完成後,繼續調用train.py進行訓練,模型選擇Plato,任務選擇NextSentencePrediction(注意區別)。訓練打分模型。

第五步:分別用save_inference_model.py導出PLATO模型和打分模型NSP。

通過這些步,模型訓練完成。用infer.py預測時,若是使用PLATO模型,須要指定打分方式--ranking_score,若是選擇nsp_score,則須要設定打分模型爲NSP。以上具體過程後邊會細講。

4 具體操做

4.1 數據準備

Plato-2模型的輸入採用了token,role,turn,position相融合的表示方式。在訓練和測試過程當中,咱們須要搞清楚文本數據須要通過怎樣的轉化才能做爲輸入,以及輸出數據須要怎樣的處理才能轉換成文本。目前咱們能夠獲取各類開放的對話訓練集,如微博,騰訊,華爲等提供的比賽用的數據集。

4.1.1 中文分詞

中文必須面對的一個問題就是如何實現分詞。在公開的開放域對話數據集中,大多數已經作了分詞,然而真實場景中語句是不可能時時刻刻都被分詞了的。在Knover的源碼中,對輸入的處理是經過了sentencepiece工具(BERT也使用的這個)。sentencepiece提供了一種方便快捷的分詞操做,咱們能夠直接將整個數據集放進去,設定分詞的單元數量,而後等待訓練出一個好用的分詞模型(會輸出一個預訓練模型,以後對每一個語句都會用這個模型進行編碼和解碼,即分詞,轉換成數字編碼,輸出再轉換回句子)。Knover中訓練必須輸入的參數spm_model,就是對應sentencepiece的預訓練模型。咱們固然能夠本身訓練一個sentencepiece的預訓練模型出來,可是考慮到分詞模型對效果的影響,推薦你們使用千言多技能對話中給出的baseline模型(luge-dialogue)中附帶的spm.model文件,這個文件分詞的效果已經很是出色了。固然,別忘了搭配詞表vocab.txt使用。目前這個比賽已經關閉,luge-dialogue這個模塊能夠在Konver官網得到。

仔細分析luge的spm.model咱們能夠發現,這個預訓練模型實際上是根據已經分詞的句子訓練的,雖然說如此,由於分詞單元足夠多,也覆蓋了全部常見的單箇中文詞。咱們能夠直接把語句送入獲得編碼,也能夠先用jieba分詞預先分一次(也能夠用其餘分詞工具),而後再編碼。用sentencepiece模型的例子以下(文件exams/do_sentencepiece.py):

import sentencepiece as sp
import jieba
text = "我今天作了一頓豐盛的晚餐!"

SPM = sp.SentencePieceProcessor()
SPM.load('spm.model')
# 直接分詞
ids = SPM.encode_as_ids(text)
print(ids)
print(SPM.decode_ids(ids))

# 先用jieba分詞,再用sentencepiece編碼
text = ' '.join(list(jieba.cut(text)))
ids = SPM.encode_as_ids(text)
print(ids)
print(SPM.decode_ids(ids))

4.1.2 文本的輸入

Plato對文本輸入的支持仍是挺多樣化的,它支持直接輸入原始文本,也支持輸入通過tokenize的分詞序列,或者是已經編碼(encoded)的數字序列。可是不管Plato支持的格式如何,在進行訓練和預測以前,都會轉換成可以被識別的標準格式。在Knover中,這個格式是經過定義的Record完成的。Record的定義以下:

from collections import namedtuple
Record = namedtuple("Record", fields, defaults=(None,) * len(fields))

在解釋fields的值以前,咱們先來思考一下Plato須要哪些輸入。在完成一段對話時,咱們一般會綜合對話的歷史和本身所知的歷史知識來進行判斷,來決定本身將要回答什麼。而在對話生成中,這些信息也是須要考慮的。所以,Plato須要的輸入有兩個,首先,是當前對方的問話,其次是已經進行過的歷史對話信息,最後是背景知識。因爲各類條件的限制,背景知識可能並無辦法獲取,因此至少須要的是已進行的歷史對話信息,和此時對方的問話。進一步,咱們須要考慮更多的信息:若是紀錄了歷史對話,咱們如何判斷每段對話的起始位置,如何判斷從何時開始生成須要的回答,在訓練集中,咱們還要知道哪一部分是訓練中給出的回答用於調整模型的參數。

在這裏插入圖片描述

上圖給出了Plato模型須要的輸入,固然這些是以Embedding的形式給出的,而Embedding是在模型中轉化的,它在轉化以前是以數字編碼存在的。Embedding如今已是語言處理技術的標配了,它把每個標記映射到空間中,增長其表徵能力。咱們暫時忽略最前邊的latent,它是表示不一樣回答方式的因變量,用於Plato在衆多可能回答中選擇正確的回答,咱們這裏不關心這個是怎麼實現的,因此不展開討論。在latent以後,有contex和response兩個內容,其中context包含了衆多信息:歷史對話,背景知識,以及對話與對話之間分隔的符號[EOS/EOU], [BOS/BOS]等等,若是有背景知識的話,也會列到context中。response則是訓練中須要的部分,在預測中這一部分是空的。

TokenEmbeddings表示各語言單元的Embedding(詞向量);RoleEmbeddings是各個語言單元在其中扮演的角色,這個主要是用來區份內容是context(EA)仍是response(EB)(亦或是背景知識,背景知識能夠做爲response的角色,也能夠單獨成爲一類,即EC);TurnEmbeddings表示每一部分在當前回合中的相對回合數(PLATO2中已經不存在這一項);PositionEmbeddings則是每一個語言單元的位置,通常是range(0, len(context))。

知道了這些,咱們回到Record上來看這個輸入應該怎麼獲得。由定義可知,Record是帶名稱的元組,這樣咱們立馬能夠知道,這個元組是經過名稱來調用其中的內容的。fields的內容是什麼呢?從官方的源碼中能夠總結出:fields = [「token_ids」, 「type_ids」, 「pos_ids」, 「tgt_start_idx」, 「data_id」]。也就是說,輸入須要給出5個部分,token_ids就是處理過的語言單位的編碼;type_ids就是個語言單位扮演的角色,是context仍是response;pos_ids是各個語言單位的位置;tgt_start_idx是回覆生成的開始位置,也即context的最後一個詞的位置;data_id就是這個訓練樣本的標記。
以下給出一個例子,能夠清楚的知道一個輸入是如何造成的(文件exams/input.py):

from collections import namedtuple

fields = ["token_ids", "type_ids", "pos_ids", "tgt_start_idx", "data_id"]
Record = namedtuple("Record", fields, defaults=(None,) * len(fields))
# 新的會話
question = '我剛剛去動物園了。'
# 歷史對話
history = '你好?[SEP] 你好,談談你本身吧?[SEP] 我今天過得很開心呢![SEP] 是嘛,你今天干了什麼?'
# 背景知識
background = '天氣:晴朗,地點:北京,人物:男孩,動物園,熊貓'
# 回答
answer = '北京動物園吧,那裏的熊貓很受歡迎呢!'

question = SPM.encode_as_ids(question)
history = [SPM.encode_as_ids(text) for text in history.split("[SEP]")]
background = SPM.encode_as_ids(background)
answer = SPM.encode_as_ids(answer)

token_ids = []
type_ids = []
data_id = 0  # 若是樣本多的話,會按排序進行標記

token_ids += [0] + background + [2]  # 0 表示語句開頭[BOS],2表示句子結尾[EOS]
type_ids += [0] + len(background) * [0] + [0]  # 0 表示context類, 1表示response類

for line in history:
    token_ids += line + [2]
    type_ids += len(line) * [0] + [0]

token_ids += question + [2]
type_ids += len(question) * [0] + [0]

token_ids += [0] + answer + [2]
type_ids += [1] + len(answer) * [1] + [1]  # 注意符號的變化

fields_value = {}
fields_value["token_ids"] = token_ids
fields_value["type_ids"] = type_ids
fields_value["pos_ids"] = list(range(len(type_ids)))
fields_value["tgt_start_idx"] = fields_value["pos_ids"][-1]
fields_value["data_id"] = data_id

record = Record(**fields_value)
print(record)

4.1.3 Knover支持的輸入

--data_format: 輸入的文件內容形式

raw: 未進行處理標記和編碼的純文本(.txt, .tsv)每行表明一個樣本,對話之間用"[SEP]「分開,對於訓練樣本,須要用」\t"隔開並加上回復語句。

例子:「你是誰?[SEP] 你猜![SEP] 別鬧! 我是你的小甜甜!」

或者分詞後的:「你 是 誰 ?[SEP] 你 猜 ![SEP] 別 鬧 ! 我 是 你的 小甜甜 !」

‘tolenized’: 進行標記的文本(.txt, .tsv)每行表明一個樣本,對話之間用"[SEP]「分開,對於訓練樣本,須要用」\t"隔開並加上回復語句。

例子:「你_ 是_ 誰_ ?[SEP] 你_ 猜_ ![SEP] 別_ 鬧_ ! 我_ 是_ 你的 小甜甜 !」,

須要注意的是,標記後的形式是如何的與選擇的vocab.txt有關,具體要看vocab.txt內標記的詞是什麼樣子的。

‘numerical’: 進行編碼的數字。必須輸入的有三個類型(token_ids, type_ids, pos_ids)並依次用";"隔開,token_ids須要標記句子的開始(1)和結束(0)。而是否有回覆則是用type_ids來標記的。

例子:

訓練樣本表示爲"1 23 45 3000 45 89 0 11 32 33 89 0; 0 0 0 0 0 0 0 1 1 1 1 1; 0 1 2 3 4 5 6 7 8 9 10 11";

預測用樣本爲"1 23 45 3000 45 89 0; 0 0 0 0 0 0 0 1 ; 0 1 2 3 4 5 6 7",注意在type_ids中加"1"用以定位tgt_start_ids。

--file_format: 輸入的文件組織形式

file: 只有一個文件。

filelist: 多個文件,全部文件都記錄在形如train_filelist的文件裏,代表多個文件的地址,每一行爲一個文件。

4.2 定義配置

因爲在訓練模型的時候,須要輸入–config_path,這個參數用來讀取模型的配置(Transformer層數量等等),這裏咱們須要定義兩個模型的配置文件(**.json)。以下參數生成兩個配置文件,配置即爲我數據集中附帶的模型的配置,若是有興趣和算力,能夠本身改配置訓練,最有效的參數是num_hidden_layers和num_attention_heads,增長這些值會增長模型的規模。

import json

## 定義UnifiedTransformer的參數
key = {'pre_encoder_cmd': 'd', 'preprocess_cmd': 'n', 'postprocess_cmd': 'da', 'post_cls_cmd': 'n', 'cls_bias': True,
 'attention_probs_dropout_prob': 0.1, 'hidden_act': 'gelu', 'hidden_dropout_prob': 0.1, 'hidden_size': 768, 
 'initializer_range': 0.02, 'max_position_embeddings': 512, 'num_attention_heads': 12, 
 'num_hidden_layers': 12, 'type_vocab_size': 2, 'role_type_size': 32, 'vocab_size': 30004}
f = open("12L.json", "w")
json_data = json.dump(key, f)
f.close()

## 定義Plato的參數
key = {'pre_encoder_cmd': 'd', 'preprocess_cmd': 'n', 'postprocess_cmd': 'da', 'post_cls_cmd': 'n', 'cls_bias': True,
 'attention_probs_dropout_prob': 0.1, 'hidden_act': 'gelu', 'hidden_dropout_prob': 0.1, 'hidden_size': 768, 
 'initializer_range': 0.02, 'max_position_embeddings': 512, 'latent_type_size': 20, 'num_attention_heads': 12, 
 'num_hidden_layers': 12, 'type_vocab_size': 2, 'role_type_size': 32, 'vocab_size': 30004}
f = open("12L_P.json", "w")
json_data = json.dump(key, f)
f.close()

建議可操做參數:

hidden_size: 隱含層尺寸。

max_position_embedding: 最大位置編碼,規定了可接收樣本的最大長度,也即輸入token_ids的最大長度,太長會被截斷。

num_attention_heads: 多頭注意力的數量,參考注意力機制。

num_hidden_layers: Transformer層數,參考注意力機制。

vocab_size: 詞表規模,即有多少個可編碼的詞單元。

latent_type_size: 僅Plato模型可設置,即隱變量z的規模,決定了文本生成階段生成回答的次數,生成後用打分機制選取最好的回答。

4.3 訓練命令

訓練UnifiedTransformer:

python Knover/train.py \
--model UnifiedTransformer --task DialogGeneration --vocab_path Knover/config/vocab.txt --spm_model_file Knover/config/spm.model \
--train_file pro_data/train.txt --valid_file pro_data/valid.txt --data_format numerical --file_format file --config_path Knover/config/12L.json \
--init_checkpoint Knover/latest_model/ut_model \
--in_tokens True --batch_size 16000 -lr 1e-5 --warmup_steps 1000 --weight_decay 0.01 --num_epochs 20 \
--max_src_len 384 --max_tgt_len 128 --max_seq_len 512 \
--log_step 100 --validation_steps 20000 --save_steps 5000 \
--save_path Knover/output \
--is_distributed False \
--is_cn True \
--start_step ??

訓練PLATO:

python Knover/train.py \
--model Plato --task DialogGeneration --vocab_path Knover/config/vocab.txt --spm_model_file Knover/config/spm.model \
--train_file pro_data/train.txt --valid_file pro_data/valid.txt --data_format numerical --file_format file --config_path Knover/config/12L_P.json \
--init_checkpoint Knover/latest_model/pt_model \
--in_tokens True --batch_size 1000 -lr 1e-5 --warmup_steps 1000 --weight_decay 0.01 --num_epochs 10 \
--max_src_len 384 --max_tgt_len 128 --max_seq_len 512 \
--log_step 100 --validation_steps 20000 --save_steps 100 \
--save_path Knover/output \
--is_cn True

訓練NSPModel打分模型:

python Knover/train.py \
--model NSPModel --task NextSentencePrediction --vocab_path Knover/config/vocab.txt --spm_model_file Knover/config/spm.model \
--train_file pro_data/train.txt --valid_file pro_data/valid.txt --data_format numerical --file_format file --config_path Knover/config/12L_P.json \
--init_checkpoint Knover/latest_model/pt_model \
--in_tokens True --batch_size 1000 -lr 4*1e-4 --warmup_steps 1000 --weight_decay 0.01 --num_epochs 10 \
--max_src_len 384 --max_tgt_len 128 --max_seq_len 512 \
--log_step 100 --validation_steps 20000 --save_steps 100 \
--save_path Knover/output \
--mix_negative_sample True

若是但願提速,能夠在百度AiStudio上用腳本進行,代碼以下(文件exams/distributed_training.py,也能夠直接訪問https://aistudio.baidu.com/aistudio/clusterprojectdetail/1154630 進行fork後運行)

# coding=utf-8

###### 歡迎使用腳本任務,讓咱們首選熟悉下一些使用規則吧 ###### 

# 數據集文件目錄
datasets_prefix = '/root/paddlejob/workspace/train_data/datasets/'

# 數據集文件具體路徑請在編輯項目狀態下,經過左側導航欄「數據集」中文件路徑拷貝按鈕獲取
train_datasets =  '經過路徑拷貝獲取真實數據集文件路徑 '

# 輸出文件目錄. 任務完成後平臺會自動把該目錄全部文件壓縮爲tar.gz包,用戶能夠經過「下載輸出」能夠將輸出信息下載到本地.
output_dir = "/root/paddlejob/workspace/output"

# 日誌記錄. 任務會自動記錄環境初始化日誌、任務執行日誌、錯誤日誌、執行腳本中全部標準輸出和標準出錯流(例如print()),用戶能夠在「提交」任務後,經過「查看日誌」追蹤日誌信息

import os

if __name__ == '__main__':
    
    print(os.getcwd())
    print("預裝依賴包")
    os.system("pip install -i https://mirror.baidu.com/pypi/simple --upgrade pip")
    os.system("pip install -i https://mirror.baidu.com/pypi/simple sentencepiece")
    print("解壓Knover模塊")
    #os.system("unzip /root/paddlejob/workspace/train_data/datasets/data56424/Knover.zip")
    os.system("unzip /root/paddlejob/workspace/train_data/datasets/data57647/Knover.zip")
    os.system("unzip /root/paddlejob/workspace/train_data/datasets/data57647/model.zip")
    os.system("unzip /root/paddlejob/workspace/train_data/datasets/data57647/NSP.zip")
    os.system("unzip /root/paddlejob/workspace/train_data/datasets/data57647/test_2.zip")
    print("解壓數據集")
    #os.system("unzip /root/paddlejob/workspace/train_data/datasets/data56424/pro_data.zip")
    
    print("開始訓練")
    os.system("export CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7")
    os.system("cd ./home/aistudio/Knover/latest_model/ && ls -a")
    
    #####################################################PARAMETERS######################################################
    epochs = 1
    start_step = 0
    lr = 1e-4
    model = "Plato"
    batch_size = 1
    model_name = "pt_model"  # {"ut_model": UnifiedTransformer, "pt_model": Plato}
    in_tokens = True  # infer.py 中設爲False
    
    config_name = "12L_P.json"  # {"12L.json", "12L_P.json", "24L.json", "24L_P.json"}, P is for Plato model
    
    func_py = "infer.py"  # {"train.py", "infer.py"}
    
    split_size = 5000  # infer.py 運行時切分文件所含樣本最大數量
    ####################################################################################################################
    
    if func_py == 'train.py':
        if model == 'Plato' or model == 'UnifiedTransformer':
            args = "--model {} --task DialogGeneration --vocab_path ./home/aistudio/Knover/config/vocab.txt --spm_model_file ./home/aistudio/Knover/config/spm.model \
                --train_file ./home/aistudio/pro_data/train.txt --valid_file ./home/aistudio/pro_data/valid.txt --data_format numerical --file_format file --config_path ./home/aistudio/Knover/config/{} \
                --in_tokens {} --batch_size {} -lr {} --warmup_steps 1000 --weight_decay 0.01 --num_epochs {} \
                --max_src_len 384 --max_tgt_len 128 --max_seq_len 512 \
                --log_step 100 --validation_steps 5000 --save_steps 100 \
                --is_distributed True is_cn True --start_step {} \
                --init_checkpoint ./model/{} \
                --save_path /root/paddlejob/workspace/output \
                ".format(model, config_name, in_tokens, batch_size, lr, epochs, start_step, model_name)
            os.system("python -m paddle.distributed.launch ./home/aistudio/Knover/{} {}".format(func_py, args))
        elif model == 'NSPModel':
            args = "--model {} --task NextSentencePrediction --vocab_path ./home/aistudio/Knover/config/vocab.txt --spm_model_file ./home/aistudio/Knover/config/spm.model \
                --train_file ./home/aistudio/pro_data/train.txt --valid_file ./home/aistudio/pro_data/valid.txt --data_format numerical --file_format file --config_path ./home/aistudio/Knover/config/{} \
                --in_tokens {} --batch_size {} -lr {} --warmup_steps 1000 --weight_decay 0.01 --num_epochs {} \
                --max_src_len 384 --max_tgt_len 128 --max_seq_len 512 \
                --log_step 100 --validation_steps 5000 --save_steps 100 \
                --is_distributed True --start_step {} \
                --init_checkpoint ./model/{} \
                --save_path /root/paddlejob/workspace/output \
                --mix_negative_sample True \
                ".format(model, config_name, in_tokens, batch_size, lr, epochs, start_step, model_name)
            os.system("python -m paddle.distributed.launch ./home/aistudio/Knover/{} {}".format(func_py, args))
        else:
            raise ValueError("Only support Plato, UnifiedTransformer, and NSPModel but received %s" % model)

4.4 導出模型

保存UnifiedTransformer

python Knover/save_inference_model.py \
--model UnifiedTransformer \
--do_generation true \
--task DialogGeneration \
--vocab_path Knover/config/vocab.txt --spm_model_file Knover/config/spm.model \
--init_checkpoint Knover/latest_model/pt_model \
--inference_model_path UnifiedTransformerModel \
--config_path Knover/config/12L.json

保存NSPModel:

python Knover/save_inference_model.py \
--model NSPModel \
--task NextSentencePrediction \
--vocab_path Knover/config/vocab.txt --spm_model_file Knover/config/spm.model \
--init_checkpoint Knover/latest_model/nsp_model \
--inference_model_path NSP \
--config_path Knover/config/12L_P.json

保存Plato

python Knover/save_inference_model.py \
--model Plato \
--do_generation true \
--task DialogGeneration \
--vocab_path Knover/config/vocab.txt --spm_model_file Knover/config/spm.model \
--init_checkpoint Knover/latest_model/pt_model \
--inference_model_path Plato \
--config_path Knover/config/12L_P.json

4.5 預測

python Knover/infer.py \
--model Plato --task DialogGeneration --vocab_path Knover/config/vocab.txt --spm_model_file Knover/config/spm.model \
--infer_file pro_data/test.txt --data_format numerical --file_format file --config_path Knover/config/12L_P.json \
--init_checkpoint Knover/latest_model/pt_model \
--batch_size 1 \
--max_src_len 384 --max_tgt_len 128 --max_seq_len 512 \
--output_name response \
--do_generation True --num_samples 20 --topk 5 --is_cn True \
--save_path Knover/output --log_step 100

固然,也能夠經過時生成的NSPModel和Plato來預測,代碼以下:

python Knover/infer.py \
--model Plato --task DialogGeneration --vocab_path Knover/config/vocab.txt --spm_model_file Knover/config/spm.model \
--infer_file pro_data/test.txt --data_format numerical --file_format file --config_path Knover/config/12L_P.json \
--init_pretraining_params Plato --nsp_inference_model_path NSP --ranking_score nsp_score \
--batch_size 1 \
--max_src_len 384 --max_tgt_len 128 --max_seq_len 512 \
--output_name response \
--do_generation True --num_samples 20 --topk 5 --is_cn True \
--do_generation true --save_path Knover/output --log_step 1
下載安裝命令

## CPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

本文同步分享在 博客「fiyen123」(CSDN)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索