概述
自然語言處理NLP任務的實現,相比較以前基於傳統機器學習算法實現方法,現在越來越集中使用大模型來實現。
通過——數據標註-模型訓練-模型調優/微調-模型壓縮-預測部署的大模型流程,覆蓋NLP多場景滿足開發者落地實現與靈活定製的需求。
PaddleNLP是其中典型的NLP解決方案庫,通過聚合業界優質預訓練模型並提供開箱即用的開發體驗,覆蓋NLP多場景的模型庫搭配產業實踐範例可滿足開發者靈活定製的需求。
預訓練基座模型主要以ERINE系列大模型爲主,畢竟是自家的噻。
之前相關的NLP系列文檔也是基於預訓練大模型的解決方案來實現的。可參考:
聊聊PaddleNLP庫與層次多標籤文本分類任務
聊聊層次多標籤分類NLP任務的實踐
UIE
UIE:Universal Information Extraction,通用信息抽取統一框架。官方文檔:UIE。
該框架實現了實體抽取、關係抽取、事件抽取、情感分析等任務的統一建模,並使得不同任務間具備良好的遷移和泛化能力。PaddleNLP借鑑論文的方法,基於ERNIE 3.0知識增強預訓練模型,訓練並開源了首箇中文通用信息抽取模型UIE。該模型可以支持不限定行業領域和抽取目標的關鍵信息抽取,實現零樣本快速冷啓動,並具備優秀的小樣本微調能力,快速適配特定的抽取目標。
開箱即用
paddlenlp.Taskflow
提供通用信息抽取、評價觀點抽取等能力,可抽取多種類型的信息,包括但不限於命名實體識別(如人名、地名、機構名等)、關係(如電影的導演、歌曲的發行時間等)、事件(如某路口發生車禍、某地發生地震等)、以及評價維度、觀點詞、情感傾向等信息。用戶可以使用自然語言自定義抽取目標,無需訓練即可統一抽取輸入文本中的對應信息。實現開箱即用,並滿足各類信息抽取需求。
以實體抽取任務爲例:
命名實體識別(Named Entity Recognition,簡稱NER),是指識別文本中具有特定意義的實體。在開放域信息抽取中,抽取的類別沒有限制,用戶可以自己定義。
- 例如抽取的目標實體類型是"時間"、"選手"和"賽事名稱", schema構造如下:
['時間', '選手', '賽事名稱']
調用示例:
>>> from pprint import pprint
>>> from paddlenlp import Taskflow
>>> schema = ['時間', '選手', '賽事名稱'] # Define the schema for entity extraction
>>> ie = Taskflow('information_extraction', schema=schema)
>>> pprint(ie("2月8日上午北京冬奧會自由式滑雪女子大跳臺決賽中中國選手谷愛凌以188.25分獲得金牌!")) # Better print results using pprint
[{'時間': [{'end': 6,
'probability': 0.9857378532924486,
'start': 0,
'text': '2月8日上午'}],
'賽事名稱': [{'end': 23,
'probability': 0.8503089953268272,
'start': 6,
'text': '北京冬奧會自由式滑雪女子大跳臺決賽'}],
'選手': [{'end': 31,
'probability': 0.8981548639781138,
'start': 28,
'text': '谷愛凌'}]}]
- 例如抽取的目標實體類型是"腫瘤的大小"、"腫瘤的個數"、"肝癌級別"和"脈管內癌栓分級", schema構造如下:
['腫瘤的大小', '腫瘤的個數', '肝癌級別', '脈管內癌栓分級']
在上例中我們已經實例化了一個Taskflow對象,這裏可以通過set_schema方法重置抽取目標。調用示例:
>>> schema = ['腫瘤的大小', '腫瘤的個數', '肝癌級別', '脈管內癌栓分級']
>>> ie.set_schema(schema)
>>> pprint(ie("(右肝腫瘤)肝細胞性肝癌(II-III級,梁索型和假腺管型),腫瘤包膜不完整,緊鄰肝被膜,侵及周圍肝組織,未見脈管內癌栓(MVI分級:M0級)及衛星子竈形成。(腫物1個,大小4.2×4.0×2.8cm)。"))
[{'肝癌級別': [{'end': 20,
'probability': 0.9243267447402701,
'start': 13,
'text': 'II-III級'}],
'腫瘤的個數': [{'end': 84,
'probability': 0.7538413804059623,
'start': 82,
'text': '1個'}],
'腫瘤的大小': [{'end': 100,
'probability': 0.8341128043459491,
'start': 87,
'text': '4.2×4.0×2.8cm'}],
'脈管內癌栓分級': [{'end': 70,
'probability': 0.9083292325934664,
'start': 67,
'text': 'M0級'}]}]
UIE支持多種NLP任務,畢竟是統一信息抽取框架。其它的任務可以參考官方文檔。
基座模型
肯定是自家的預訓練基座啦。
模型 | 結構 | 語言 |
---|---|---|
uie-base (默認) | 12-layers, 768-hidden, 12-heads | 中文 |
uie-base-en | 12-layers, 768-hidden, 12-heads | 英文 |
uie-medical-base | 12-layers, 768-hidden, 12-heads | 中文 |
uie-medium | 6-layers, 768-hidden, 12-heads | 中文 |
uie-mini | 6-layers, 384-hidden, 12-heads | 中文 |
uie-micro | 4-layers, 384-hidden, 12-heads | 中文 |
uie-nano | 4-layers, 312-hidden, 12-heads | 中文 |
uie-m-large | 24-layers, 1024-hidden, 16-heads | 中、英文 |
uie-m-base | 12-layers, 768-hidden, 12-heads | 中、英文 |
uie模型是基於ERINE基座模型訓練出來的。
微調—定製化
其實在我個人的角度來看,上述的內容在很多的框架、平臺都已經有了;譬如Modelscope,我現在養成習慣,遇到啥NLP相關的、大模型相關的,就去Modelscope找解決策略。但在Modelscope上有個最大的問題,當然這是我個人的看法——微調支持不夠,很多的模型/庫壓根沒有微調。老實說,這的確是幫助不大,在很多時候我們需要的是可以接入的定製化實現。
這也正常,畢竟如果開放了微調,支持靈活的定製化,對開源方就不太友好了。
而相比較來說,PaddleNLP的微調支持就很到位了。
數據標註
基於doccano標註平臺做數據標註。可參考: 聊聊層次多標籤分類NLP任務的實踐。
模型微調
薦使用 Trainer API對模型進行微調。只需輸入模型、數據集等就可以使用 Trainer API 高效快速地進行預訓練、微調和模型壓縮等任務,可以一鍵啓動多卡訓練、混合精度訓練、梯度累積、斷點重啓、日誌顯示等功能,Trainer API 還針對訓練過程的通用訓練配置做了封裝,比如:優化器、學習率調度等。
使用下面的命令,使用 uie-base 作爲預訓練模型進行模型微調,將微調後的模型保存至$finetuned_model:
單卡啓動:
export finetuned_model=./checkpoint/model_best
python finetune.py \
--device gpu \
--logging_steps 10 \
--save_steps 100 \
--eval_steps 100 \
--seed 42 \
--model_name_or_path uie-base \
--output_dir $finetuned_model \
--train_path data/train.txt \
--dev_path data/dev.txt \
--max_seq_length 512 \
--per_device_eval_batch_size 16 \
--per_device_train_batch_size 16 \
--num_train_epochs 20 \
--learning_rate 1e-5 \
--label_names "start_positions" "end_positions" \
--do_train \
--do_eval \
--do_export \
--export_model_dir $finetuned_model \
--overwrite_output_dir \
--disable_tqdm True \
--metric_for_best_model eval_f1 \
--load_best_model_at_end True \
--save_total_limit 1
模型評估
可忽略
模型預測
paddlenlp.Taskflow裝載定製模型,通過task_path指定模型權重文件的路徑,路徑下需要包含訓練好的模型權重文件model_state.pdparams。
>>> from pprint import pprint
>>> from paddlenlp import Taskflow
>>> schema = ['出發地', '目的地', '費用', '時間']
# 設定抽取目標和定製化模型權重路徑
>>> my_ie = Taskflow("information_extraction", schema=schema, task_path='./checkpoint/model_best')
>>> pprint(my_ie("城市內交通費7月5日金額114廣州至佛山"))
[{'出發地': [{'end': 17,
'probability': 0.9975287467835301,
'start': 15,
'text': '廣州'}],
'時間': [{'end': 10,
'probability': 0.9999476678061399,
'start': 6,
'text': '7月5日'}],
'目的地': [{'end': 20,
'probability': 0.9998511131226735,
'start': 18,
'text': '佛山'}],
'費用': [{'end': 15,
'probability': 0.9994474579292856,
'start': 12,
'text': '114'}]}]
模型部署
- 模型導出:模型訓練、壓縮時已經自動進行了靜態圖的導出以及 tokenizer 配置文件保存,保存路徑${finetuned_model} 下應該有 .pdimodel、.pdiparams 模型文件可用於推理。
- 模型部署:
# UIE 模型 CPU 推理
python deploy/python/infer.py --model_dir ./checkpoint/model_best --device cpu
# UIE 模型 GPU 推理
python deploy/python/infer.py --model_dir ./checkpoint/model_best --device gpu
總結
PaddleNLP是基於預訓練大模型的NLP任務解決方案庫,因此其實踐流程其實都是一樣的:數據標註-模型訓練-模型調優/微調-模型壓縮-預測部署。通過對PaddleNLP庫的實踐與瞭解熟悉,我個人覺得,非常有助於掌握NLP與大模型在實際應用中的落地。建議大家多瞭解學習。
更多PaddleNLP與大模型的文章,請上個人公衆號查閱: