零樣本文字分類應用:基於UTC的醫療意圖多分類,打通資料標註-模型訓練-模型調優-預測部署全流程。
1.通用文字分類技術UTC介紹
本專案提供基於通用文字分類 UTC(Universal Text Classification) 模型微調的文字分類端到端應用方案,打通資料標註-模型訓練-模型調優-預測部署全流程,可快速實現文字分類產品落地。
文字分類是一種重要的自然語言處理任務,它可以幫助我們將大量的文字資料進行有效的分類和歸納。實際上,在日常生活中,我們也經常會用到文字分類技術。例如,我們可以使用文字分類來對新聞報導進行分類,對電子郵件進行分類,對社交媒體上的評論進行情感分析等等。但是,文字分類也面臨著許多挑戰。其中最重要的挑戰之一是資料稀缺。由於文字資料往往非常龐大,因此獲取足夠的訓練資料可能非常困難。此外,不同的文字分類任務也可能面臨著領域多變和任務多樣等挑戰。為了應對這些挑戰,PaddleNLP推出了一項零樣本文字分類應用UTC。該應用透過統一語義匹配方式USM(Unified Semantic Matching)來將標籤和文字的語義匹配能力進行統一建模。這種方法可以幫助我們更好地理解文字資料,並從中提取出有用的特徵資訊。
UTC具有低資源遷移能力,可以支援通用分類、評論情感分析、語義相似度計算、蘊含推理、多項式閱讀理解等多種“泛分類”任務。這使得開發者可以更加輕鬆高效地實現多工文字分類資料標註、訓練、調優和上線,從而降低文字分類技術門檻。
總之,文字分類是一項重要的自然語言處理任務,它可以幫助我們更好地理解和歸納文字資料。儘管它面臨著許多挑戰,但是透過使用PaddleNLP的零樣本文字分類應用UTC,開發者們可以簡單高效實現多工文字分類資料標註、訓練、調優、上線,降低文字分類落地技術門檻。
1.1 分類落地面臨難度
分類任務看似簡單,然而在產業級文字分類落地實踐中,面臨著諸多挑戰:
-
任務多樣:單標籤、多標籤、層次標籤、大規模標籤等不同的文字分類任務,需要開發不同的分類模型,模型架構往往特化於具體任務,難以使用統一形式建模;
-
資料稀缺:部分領域資料稀缺,難以獲取,且領域專業性使得資料標註門檻高;
-
標籤遷移:不同領域的標籤多樣,並且遷移難度大,尤其不同領域間的標籤知識很難遷移。
1.2 UTC亮點
1.2.1 多工統一建模
在傳統技術方案中,針對不同的分類任務需要構建多個分類模型,模型需單獨訓練且資料和知識不共享。而在UTC方案下,單個模型能解決所有分類需求,包括但不限於單標籤分類、多標籤分類、層次標籤分類、大規模事件標籤檢測、蘊含推理、語義相似度計算等,降低了開發成本和機器成本。
1.2.2 零樣本分類和小樣本遷移能力強
UTC透過大規模多工預訓練後,可以適配不同的行業領域,不同的分類標籤,僅標註了幾條樣本,分類效果就取得大幅提升,大大降低標註門檻和成本。
在醫療、金融、法律等領域中,無需訓練資料的零樣本情況下UTC效果平均可達到70%+(如下表所示),標註少樣本也可帶來顯著的效果提升:每個標籤僅僅標註1條樣本後,平均提升了10個點!也就是說,即使在某些場景下表現欠佳,人工標幾個樣本,丟給模型後就會有大幅的效果提升。
1.3 UTC技術思路
UTC基於百度最新提出的統一語義匹配框架USM(Unified Semantic Matching)[1],將分類任務統一建模為標籤與文字之間的匹配任務,對不同標籤的分類任務進行統一建模。具體地說:
- 為了實現任務架構統一,UTC設計了標籤與文字之間的詞對連線操作(Label–>CLS-Token Linking),這使得模型能夠適應不同領域和任務的標籤資訊,並按需求進行分類,從而實現了開放域場景下的通用文字分類。
例如,對於事件檢測任務,可將一系列事件標籤拼接為[L]上映[L]奪冠[L]下架 ,然後與原文字一起作為整體輸入到UTC中,UTC將不同標籤識別符號[L]與[CLS]進行匹配,可對不同標籤型別的分類任務統一建模,直接上圖:
- 為了實現通用能力共享,讓不同領域間的標籤知識跨域遷移,UTC構建了統一的異質監督學習方法進行多工預訓練,使不同領域任務具備良好的零/少樣本遷移效能。統一的異質監督學習方法主要包括三種不同的監督訊號:
- 直接監督:分類任務直接相關的資料集,如情感分類、新聞分類、意圖識別等。
- 間接監督:分類任務間接相關的資料集,如選項式閱讀理解、問題-文章匹配等。
- 遠端監督:標籤知識庫或層級標題與文字對齊後弱標註資料。
更多內容參考論文見文末連結 or fork一下專案論文已上傳
2.文字分類任務Label Studio教程
2.1 Label Studio安裝
以下標註示例用到的環境配置:
- Python 3.8+
- label-studio == 1.7.2
在終端(terminal)使用pip安裝label-studio:
pip install label-studio==1.7.2
安裝完成後,執行以下命令列:
label-studio start
在瀏覽器開啟http://localhost:8080/,輸入使用者名稱和密碼登入,開始使用label-studio進行標註。
2.2 文字分類任務標註
2.2.1 專案建立
點選建立(Create)開始建立一個新的專案,填寫專案名稱、描述,然後在Labeling Setup
中選擇Text Classification
。
- 填寫專案名稱、描述
- 資料上傳,從本地上傳txt格式檔案,選擇
List of tasks
,然後選擇匯入本專案
- 設定任務,新增標籤
- 資料上傳
專案建立後,可在Project/文字分類任務中點選Import
繼續匯入資料,同樣從本地上傳txt格式檔案,選擇List of tasks
。
2.2.2 標籤構建
專案建立後,可在Setting/Labeling Interface中繼續配置標籤,
預設模式為單標籤多分類資料標註。對於多標籤多分類資料標註,需要將choice
的值由single
改為multiple
。
2.2.3 任務標註
2.2.4 資料匯出
勾選已標註文字ID,選擇匯出的檔案型別為JSON
,匯出資料:
參考連結:
3.資料轉換
將匯出的檔案重新命名為label_studio.json
後,放入./data
目錄下。透過label_studio.py指令碼可轉為UTC的資料格式。
在資料轉換階段,還需要提供標籤候選資訊,放在./data/label.txt
檔案中,每個標籤佔一行。例如在醫療意圖分類中,標籤候選為["病情診斷", "治療方案", "病因分析", "指標解讀", "就醫建議", "疾病表述", "後果表述", "注意事項", "功效作用", "醫療費用", "其他"]
,也可透過options
引數直接進行配置。
這裡提供預先標註好的醫療意圖分類資料集
的檔案,可以執行下面的命令列下載資料集,我們將展示如何使用資料轉化指令碼生成訓練/驗證/測試集檔案,並使用UTC模型進行微調。
#下載醫療意圖分類資料集:
!wget https://bj.bcebos.com/paddlenlp/datasets/utc-medical.tar.gz
!tar -xvf utc-medical.tar.gz
!mv utc-medical data
!rm utc-medical.tar.gz
資料集部分展示
[{"id":26092,"annotations":[{"id":59,"completed_by":1,"result":[{"value":{"choices":["注意事項"]},"id":"7iya31L9oc","from_name":"sentiment","to_name":"text","type":"choices","origin":"manual"}],"was_cancelled":false,"ground_truth":false,"created_at":"2023-01-09T07:13:18.982993Z","updated_at":"2023-01-09T07:13:18.983032Z","lead_time":4.022,"prediction":{},"result_count":0,"task":26092,"parent_prediction":null,"parent_annotation":null}],"file_upload":"838fb89a-10-shot.txt","drafts":[],"predictions":[],"data":{"text":"燒氧割要注意那些問題"},"meta":{},"created_at":"2023-01-09T06:48:10.725717Z","updated_at":"2023-01-09T07:13:19.022666Z","inner_id":35,"total_annotations":1,"cancelled_annotations":0,"total_predictions":0,"comment_count":0,"unresolved_comment_count":0,"last_comment_updated_at":null,"project":5,"updated_by":1,"comment_authors":[]},
{"id":26091,"annotations":[{"id":4,"completed_by":1,"result":[{"value":{"choices":["病因分析"]}]
# 生成訓練/驗證集檔案:
!python label_studio.py \
--label_studio_file ./data/utc-medical/label_studio.json \
--save_dir ./data \
--splits 0.8 0.1 0.1 \
--options ./data/utc-medical/label.txt
[32m[2023-04-14 11:28:46,056] [ INFO][0m - Save 45 examples to ./data/train.txt.[0m
[32m[2023-04-14 11:28:46,057] [ INFO][0m - Save 6 examples to ./data/dev.txt.[0m
[32m[2023-04-14 11:28:46,057] [ INFO][0m - Save 6 examples to ./data/test.txt.[0m
[32m[2023-04-14 11:28:46,057] [ INFO][0m - Finished! It takes 0.00 seconds[0m
[0m
{"text_a": "老年痴呆的症狀有哪些", "text_b": "", "question": "", "choices": ["病情診斷", "治療方案", "病因分析", "指標解讀", "就醫建議", "疾病表述", "後果表述", "注意事項", "功效作用", "醫療費用", "其他"], "labels": [5]}
label_studio_file
: 從label studio匯出的資料標註檔案。save_dir
: 訓練資料的儲存目錄,預設儲存在data
目錄下。splits
: 劃分資料集時訓練集、驗證集所佔的比例。預設為[0.8, 0.1, 0.1]表示按照8:1:1
的比例將資料劃分為訓練集、驗證集和測試集。options
: 指定分類任務的類別標籤。若輸入型別為檔案,則檔案中每行一個標籤。is_shuffle
: 是否對資料集進行隨機打散,預設為True。seed
: 隨機種子,預設為1000.
備註:
- 預設情況下 label_studio.py 指令碼會按照比例將資料劃分為 train/dev/test 資料集
- 每次執行 label_studio.py 指令碼,將會覆蓋已有的同名資料檔案
- 對於從label_studio匯出的檔案,預設檔案中的每條資料都是經過人工正確標註的。
使用Label Studio 資料標註工具進行標註,如果已有標註好的本地資料集,我們需要將資料集整理為文件要求的格式,
4.模型訓練預測
多工訓練場景可分別進行資料轉換再進行混合:通用分類、評論情感分析、語義相似度計算、蘊含推理、多項式閱讀理解等眾多“泛分類”任務
##程式碼結構
├── deploy/simple_serving/ # 模型部署指令碼
├── utils.py # 資料處理工具
├── run_train.py # 模型微調指令碼
├── run_eval.py # 模型評估指令碼
├── label_studio.py # 資料格式轉換指令碼
├── label_studio_text.md # 資料標註說明文件
└── README.md
4.1 模型微調
推薦使用 PromptTrainer API 對模型進行微調,該 API 封裝了提示定義功能,且繼承自 Trainer API 。只需輸入模型、資料集等就可以使用 Trainer API 高效快速地進行預訓練、微調等任務,可以一鍵啟動多卡訓練、混合精度訓練、梯度累積、斷點重啟、日誌顯示等功能,Trainer API 還針對訓練過程的通用訓練配置做了封裝,比如:最佳化器、學習率排程等。
使用下面的命令,使用 utc-base
作為預訓練模型進行模型微調,將微調後的模型儲存至output_dir
:
4.1.1 單卡訓練
#安裝最新版本paddlenlp
!pip install --upgrade paddlenlp
# 單卡啟動:
!python run_train.py \
--device gpu \
--logging_steps 10 \
--save_steps 10 \
--eval_steps 10 \
--seed 1000 \
--model_name_or_path utc-base \
--output_dir ./checkpoint/model_best \
--dataset_path ./data/ \
--max_seq_length 512 \
--per_device_train_batch_size 2 \
--per_device_eval_batch_size 2 \
--gradient_accumulation_steps 8 \
--num_train_epochs 20 \
--learning_rate 1e-5 \
--do_train \
--do_eval \
--do_export \
--export_model_dir ./checkpoint/model_best \
--overwrite_output_dir \
--disable_tqdm True \
--metric_for_best_model macro_f1 \
--load_best_model_at_end True \
--save_total_limit 1 \
--save_plm
eval_loss: 0.3148668706417084, eval_micro_f1: 0.9848484848484849, eval_macro_f1: 0.9504132231404958, eval_runtime: 0.0757, eval_samples_per_second: 79.286, eval_steps_per_second: 39.643, epoch: 19.6957
[2023-04-13 17:02:45,941] [ INFO] - epoch = 19.6957
[2023-04-13 17:02:45,941] [ INFO] - train_loss = 0.9758
[2023-04-13 17:02:45,942] [ INFO] - train_runtime = 0:00:45.91
[2023-04-13 17:02:45,942] [ INFO] - train_samples_per_second = 19.602
[2023-04-13 17:02:45,942] [ INFO] - train_steps_per_second = 0.871
二分類時需要注意的問題
- ModuleNotFoundError: No module named 'fast_tokenizer'
安裝一下fast tokenizer
pip install --upgrade fast_tokenizer
- 開啟single_label時需要將執行指令碼中的 metric_for_best_model 引數改為accuracy
metric_value = metrics[metric_to_check]
KeyError: 'eval_macro_f1'
4.1.2 多卡訓練
如果在GPU環境中使用,可以指定gpus引數進行多卡訓練:
# !python -u -m paddle.distributed.launch --gpus "0,1,2,3" run_train.py \
# --device gpu \
# --logging_steps 10 \
# --save_steps 10 \
# --eval_steps 10 \
# --seed 1000 \
# --model_name_or_path utc-base \
# --output_dir ./checkpoint/model_best \
# --dataset_path ./data/ \
# --max_seq_length 512 \
# --per_device_train_batch_size 2 \
# --per_device_eval_batch_size 2 \
# --gradient_accumulation_steps 8 \
# --num_train_epochs 20 \
# --learning_rate 1e-5 \
# --do_train \
# --do_eval \
# --do_export \
# --export_model_dir ./checkpoint/model_best \
# --overwrite_output_dir \
# --disable_tqdm True \
# --metric_for_best_model macro_f1 \
# --load_best_model_at_end True \
# --save_total_limit 1 \
# --save_plm
該示例程式碼中由於設定了引數 --do_eval
,因此在訓練完會自動進行評估。
可配置引數說明:
single_label
: 每條樣本是否只預測一個標籤。預設為False
,表示多標籤分類。device
: 訓練裝置,可選擇 'cpu'、'gpu' 其中的一種;預設為 GPU 訓練。logging_steps
: 訓練過程中日誌列印的間隔 steps 數,預設10。save_steps
: 訓練過程中儲存模型 checkpoint 的間隔 steps 數,預設100。eval_steps
: 訓練過程中儲存模型 checkpoint 的間隔 steps 數,預設100。seed
:全域性隨機種子,預設為 42。model_name_or_path
:進行 few shot 訓練使用的預訓練模型。預設為 "utc-base", 可選"utc-xbase", "utc-base", "utc-medium", "utc-mini", "utc-micro", "utc-nano", "utc-pico"。output_dir
:必須,模型訓練或壓縮後儲存的模型目錄;預設為None
。dataset_path
:資料集檔案所在目錄;預設為./data/
。train_file
:訓練集字尾;預設為train.txt
。dev_file
:開發集字尾;預設為dev.txt
。max_seq_len
:文字最大切分長度,包括標籤的輸入超過最大長度時會對輸入文字進行自動切分,標籤部分不可切分,預設為512。per_device_train_batch_size
:用於訓練的每個 GPU 核心/CPU 的batch大小,預設為8。per_device_eval_batch_size
:用於評估的每個 GPU 核心/CPU 的batch大小,預設為8。num_train_epochs
: 訓練輪次,使用早停法時可以選擇 100;預設為10。learning_rate
:訓練最大學習率,UTC 推薦設定為 1e-5;預設值為3e-5。do_train
:是否進行微調訓練,設定該參數列示進行微調訓練,預設不設定。do_eval
:是否進行評估,設定該參數列示進行評估,預設不設定。do_export
:是否進行匯出,設定該參數列示進行靜態圖匯出,預設不設定。export_model_dir
:靜態圖匯出地址,預設為None。overwrite_output_dir
: 如果True
,覆蓋輸出目錄的內容。如果output_dir
指向檢查點目錄,則使用它繼續訓練。disable_tqdm
: 是否使用tqdm進度條。metric_for_best_model
:最優模型指標, UTC 推薦設定為macro_f1
,預設為None。load_best_model_at_end
:訓練結束後是否載入最優模型,通常與metric_for_best_model
配合使用,預設為False。save_total_limit
:如果設定次引數,將限制checkpoint的總數。刪除舊的checkpoints輸出目錄
,預設為None。--save_plm
:儲存模型進行推理部署
4.2 模型評估
透過執行以下命令進行模型評估預測:
!python run_eval.py \
--model_path ./checkpoint/model_best \
--test_path ./data/test.txt \
--per_device_eval_batch_size 16 \
--max_seq_len 512 \
--output_dir ./checkpoint_test
測試結果
[2023-04-13 17:06:59,413] [ INFO] - test_loss = 1.6392
[2023-04-13 17:06:59,413] [ INFO] - test_macro_f1 = 0.8167
[2023-04-13 17:06:59,413] [ INFO] - test_micro_f1 = 0.9394
[2023-04-13 17:06:59,413] [ INFO] - test_runtime = 0:00:00.87
[2023-04-13 17:06:59,413] [ INFO] - test_samples_per_second = 6.835
[2023-04-13 17:06:59,413] [ INFO] - test_steps_per_second = 1.139
可配置引數說明:
model_path
: 進行評估的模型資料夾路徑,路徑下需包含模型權重檔案model_state.pdparams
及配置檔案model_config.json
。test_path
: 進行評估的測試集檔案。per_device_eval_batch_size
: 批處理大小,請結合機器情況進行調整,預設為16。max_seq_len
: 文字最大切分長度,輸入超過最大長度時會對輸入文字進行自動切分,預設為512。single_label
: 每條樣本是否只預測一個標籤。預設為False
,表示多標籤分類。
4.3模型預測
paddlenlp.Taskflow
裝載定製模型,透過task_path
指定模型權重檔案的路徑,路徑下需要包含訓練好的模型權重檔案model_state.pdparams
。
!pip install onnxruntime-gpu onnx onnxconverter-common
!pip install paddle2onnx
#如果出現這個報錯 local variable 'paddle2onnx' referenced before assignment ,請安裝上述庫onnx 的包需要安裝
#中途出現一些警告可以忽視
from pprint import pprint
from paddlenlp import Taskflow
schema = ["病情診斷", "治療方案", "病因分析", "指標解讀", "就醫建議", "疾病表述", "後果表述", "注意事項", "功效作用", "醫療費用", "其他"]
# my_cls = Taskflow("zero_shot_text_classification", model="utc-base", schema=schema, task_path='/home/aistudio/checkpoint/model_best/plm', precision="fp16")
my_cls = Taskflow("zero_shot_text_classification", model="utc-base", schema=schema, task_path='/home/aistudio/checkpoint/model_best/plm')
#支援FP16半精度推理加速,需要安裝onnx
pprint(my_cls(["老年斑為什麼都長在面部和手背上","老成都市哪家內痔醫院比較好怎麼樣最好?","中性粒細胞比率偏低"]))
[2023-04-14 11:45:11,057] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load 'utc-base'.
[2023-04-14 11:45:11,059] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/utc-base/utc_base_vocab.txt
[2023-04-14 11:45:11,083] [ INFO] - tokenizer config file saved in /home/aistudio/.paddlenlp/models/utc-base/tokenizer_config.json
[2023-04-14 11:45:11,085] [ INFO] - Special tokens file saved in /home/aistudio/.paddlenlp/models/utc-base/special_tokens_map.json
[2023-04-14 11:45:11,088] [ INFO] - Assigning ['[O-MASK]'] to the additional_special_tokens key of the tokenizer
[{'predictions': [{'label': '病因分析', 'score': 0.7360146263899581}],
'text_a': '老年斑為什麼都長在面部和手背上'},
{'predictions': [{'label': '就醫建議', 'score': 0.9940570944549809}],
'text_a': '老成都市哪家內痔醫院比較好怎麼樣最好?'},
{'predictions': [{'label': '指標解讀', 'score': 0.6683004187689248}],
'text_a': '中性粒細胞比率偏低'}]
from pprint import pprint
from paddlenlp import Taskflow
schema = ["病情診斷", "治療方案", "病因分析", "指標解讀", "就醫建議", "疾病表述", "後果表述", "注意事項", "功效作用", "醫療費用", "其他"]
my_cls = Taskflow("zero_shot_text_classification", model="utc-base", schema=schema)
pprint(my_cls(["老年斑為什麼都長在面部和手背上","老成都市哪家內痔醫院比較好怎麼樣最好?","中性粒細胞比率偏低"]))
[2023-04-14 11:45:20,869] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load 'utc-base'.
[2023-04-14 11:45:20,872] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/utc-base/utc_base_vocab.txt
[2023-04-14 11:45:20,897] [ INFO] - tokenizer config file saved in /home/aistudio/.paddlenlp/models/utc-base/tokenizer_config.json
[2023-04-14 11:45:20,900] [ INFO] - Special tokens file saved in /home/aistudio/.paddlenlp/models/utc-base/special_tokens_map.json
[2023-04-14 11:45:20,903] [ INFO] - Assigning ['[O-MASK]'] to the additional_special_tokens key of the tokenizer
[{'predictions': [], 'text_a': '老年斑為什麼都長在面部和手背上'},
{'predictions': [{'label': '就醫建議', 'score': 0.9283481315032535},
{'label': '其他', 'score': 0.5083715719139965}],
'text_a': '老成都市哪家內痔醫院比較好怎麼樣最好?'},
{'predictions': [{'label': '其他', 'score': 0.9437889944553786}],
'text_a': '中性粒細胞比率偏低'}]
4.3.1 預測結果對比
模型 | 文字 | 預測結果 | 評估得分 |
---|---|---|---|
utc-base | 老年斑為什麼都長在面部和手背上 | 空 | --- |
utc-base | 老成都市哪家內痔醫院比較好怎麼樣最好? | 就醫建議/其他 | 0.92/0.51 |
utc-base | 中性粒細胞比率偏低 | 其他 | 0.94 |
utc-base+微調 | 老年斑為什麼都長在面部和手背上 | 病因分析 | 0.73 |
utc-base+微調 | 老成都市哪家內痔醫院比較好怎麼樣最好? | 就醫建議 | 0.99 |
utc-base+微調 | 中性粒細胞比率偏低 | 指標解讀 | 0.66 |
明顯可以看到在透過樣本訓練後,在test測試的結果小樣本本微調的結果顯著提升
4.3.2 各個模型見對比
Micro F1更關注整個資料集的效能,而Macro F1更關注每個類別的效能。
醫療意圖分類資料集 KUAKE-QIC 驗證集 zero-shot 實驗指標和小樣本下訓練對比:
Macro F1 | Micro F1 | 微調後 Macro F1 | 微調後 Micro F1 | |
---|---|---|---|---|
utc-xbase | 66.30 | 89.67 | ||
utc-base | 64.13 | 89.06 | 81.67(+17.54) | 93.94 (+4.88) |
utc-medium | 69.62 | 89.15 | ||
utc-micro | 60.31 | 79.14 | ||
utc-mini | 65.82 | 89.82 | ||
utc-nano | 62.03 | 80.92 | ||
utc-pico | 53.63 | 83.57 |
其餘模型就不一一驗證了,感興趣同學自行驗證。
5.模型部署
目前 UTC 模型提供基於多種部署方式,包括基於 FastDeploy 的本地 Python 部署以及 PaddleNLP SimpleServing 的服務化部署。
5.1 FastDeploy UTC 模型 Python 部署示例
以下示例展示如何基於 FastDeploy 庫完成 UTC 模型完成通用文字分類任務的 Python 預測部署,可透過命令列引數--device
以及--backend
指定執行在不同的硬體以及推理引擎後端,並使用--model_dir
引數指定執行的模型。模型目錄為 application/zero_shot_text_classification/checkpoint/model_best
(使用者可按實際情況設定)。
在部署前,參考 FastDeploy SDK 安裝文件安裝 FastDeploy Python SDK。
本目錄下提供 infer.py
快速完成在 CPU/GPU 的通用文字分類任務的 Python 部署示例。
- 依賴安裝
直接執行以下命令安裝部署示例的依賴。
# 安裝 fast_tokenizer 以及 GPU 版本 fastdeploy
pip install fast-tokenizer-python fastdeploy-gpu-python -f https://www.paddlepaddle.org.cn/whl/fastdeploy.html
以下示例展示如何基於 FastDeploy 庫完成 UTC 模型進行文字分類任務的 Python 預測部署,可透過命令列引數--device
以及--backend
指定執行在不同的硬體以及推理引擎後端,並使用--model_dir
引數指定執行的模型,具體引數設定可檢視下面[引數說明])。示例中的模型是按照 [UTC 訓練文件]匯出得到的部署模型,其模型目錄為 application/zero_shot_text_classification/checkpoint/model_best
(使用者可按實際情況設定)。
# CPU 推理
python /home/aistudio/deploy/python/infer.py--model_dir /home/aistudio/checkpoint/model_best --device cpu
# GPU 推理
python /home/aistudio/deploy/python/infer.py --model_dir /home/aistudio/checkpoint/model_best --device gpu
執行完成後返回的結果如下:
- 引數說明
引數 | 引數說明 |
---|---|
--model_dir | 指定部署模型的目錄, |
--batch_size | 輸入的batch size,預設為 1 |
--max_length | 最大序列長度,預設為 128 |
--num_omask_tokens | 最大標籤數量,預設為64 |
--device | 執行的裝置,可選範圍: ['cpu', 'gpu'],預設為'cpu' |
--device_id | 執行裝置的id。預設為0。 |
--cpu_threads | 當使用cpu推理時,指定推理的cpu執行緒數,預設為1。 |
--backend | 支援的推理後端,可選範圍: ['onnx_runtime', 'paddle', 'tensorrt', 'paddle_tensorrt'],預設為'paddle' |
--use_fp16 | 是否使用FP16模式進行推理。使用tensorrt和paddle_tensorrt後端時可開啟,預設為False |
- FastDeploy 高階用法
FastDeploy 在 Python 端上,提供 fastdeploy.RuntimeOption.use_xxx()
以及 fastdeploy.RuntimeOption.use_xxx_backend()
介面支援開發者選擇不同的硬體、不同的推理引擎進行部署。在不同的硬體上部署 UTC 模型,需要選擇硬體所支援的推理引擎進行部署,下表展示如何在不同的硬體上選擇可用的推理引擎部署 UTC 模型。
符號說明: (1) ✅: 已經支援; (2) ❔: 正在進行中; (3) N/A: 暫不支援;
硬體 | 硬體對應的介面 | 可用的推理引擎 | 推理引擎對應的介面 | 是否支援 Paddle 新格式量化模型 | 是否支援 FP16 模式 |
CPU | use_cpu() | Paddle Inference | use_paddle_infer_backend() | ✅ | N/A |
ONNX Runtime | use_ort_backend() | ✅ | N/A | ||
GPU | use_gpu() | Paddle Inference | use_paddle_infer_backend() | ✅ | N/A |
ONNX Runtime | use_ort_backend() | ✅ | ❔ | ||
Paddle TensorRT | use_paddle_infer_backend() + paddle_infer_option.enable_trt = True | ✅ | ✅ | ||
TensorRT | use_trt_backend() | ✅ | ✅ | ||
崑崙芯 XPU | use_kunlunxin() | Paddle Lite | use_paddle_lite_backend() | N/A | ✅ |
華為 昇騰 | use_ascend() | Paddle Lite | use_paddle_lite_backend() | ❔ | ✅ |
Graphcore IPU | use_ipu() | Paddle Inference | use_paddle_infer_backend() | ❔ | N/A |
# !pip install --user fast-tokenizer-python fastdeploy-gpu-python -f https://www.paddlepaddle.org.cn/whl/fastdeploy.html
#比較大1.4G 去終端安裝
在notebook執行出現問題,可能需要本地對fastdeploy應用除錯,或者有小夥伴解決了可以再評論區發表一下,一起解決。
- 在studio 目前顯示是安裝成功了,但是初始化是失敗的
File "/home/aistudio/.data/webide/pip/lib/python3.7/site-packages/fastdeploy/c_lib_wrap.py", line 166, in <module>
raise RuntimeError("FastDeploy initalized failed!")
RuntimeError: FastDeploy initalized failed!
- 在本地測試模型使用了utc-pico,cpu情況下除錯。
效果如下:
記得修改infer檔案對應的預測內容
predictor = Predictor(args, schema=["病情診斷", "治療方案", "病因分析", "指標解讀", "就醫建議", "疾病表述", "後果表述", "注意事項", "功效作用", "醫療費用", "其他"])
results = predictor.predict(["月經期間刮痧拔罐會引起身體什麼","老年斑為什麼都長在面部和手背上","成都市哪家內痔醫院比較好怎麼樣最好?","中性粒細胞比率偏低"])
推理:模型目錄需要包含:model.pdmodel等檔案
5.2 SimpleServing 的服務化部署
在 UTC 的服務化能力中我們提供基於PaddleNLP SimpleServing 來搭建服務化能力,透過幾行程式碼即可搭建服務化部署能力。
- 環境準備
使用有SimpleServing功能的PaddleNLP版本(或者最新的develop版本)
pip install paddlenlp >= 2.5.0
- Server服務啟動
進入檔案當前所在路徑
paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8190
- Client請求啟動
python client.py
-
服務化自定義引數
-
Server 自定義引數
-
schema替換
-
# Default schema
schema = ["病情診斷", "治療方案", "病因分析", "指標解讀", "就醫建議", "疾病表述", "後果表述", "注意事項", "功效作用", "醫療費用", "其他"]
* 設定模型路徑
# Default task_path
utc = Taskflow("zero_shot_text_classification", model="utc-base", task_path="../../checkpoint/model_best/plm", schema=schema)
* 多卡服務化預測
PaddleNLP SimpleServing 支援多卡負載均衡預測,主要在服務化註冊的時候,註冊兩個Taskflow的task即可,下面是示例程式碼
utc1 = Taskflow("zero_shot_text_classification", model="utc-base", task_path="../../checkpoint/model_best", schema=schema)
utc2 = Taskflow("zero_shot_text_classification", model="utc-base", task_path="../../checkpoint/model_best", schema=schema)
service.register_taskflow("taskflow/utc", [utc1, utc2])
- 更多配置
from paddlenlp import Taskflow
schema = ["病情診斷", "治療方案", "病因分析", "指標解讀", "就醫建議", "疾病表述", "後果表述", "注意事項", "功效作用", "醫療費用", "其他"]
utc = Taskflow("zero_shot_text_classification",
schema=schema,
model="utc-base",
max_seq_len=512,
batch_size=1,
pred_threshold=0.5,
precision="fp32")
-
schema
:定義任務標籤候選集合。 -
model
:選擇任務使用的模型,預設為utc-base
, 可選有utc-xbase
,utc-base
,utc-medium
,utc-micro
,utc-mini
,utc-nano
,utc-pico
。 -
max_seq_len
:最長輸入長度,包括所有標籤的長度,預設為512。 -
batch_size
:批處理大小,請結合機器情況進行調整,預設為1。 -
pred_threshold
:模型對標籤預測的機率在0~1之間,返回結果去掉小於這個閾值的結果,預設為0.5。 -
precision
:選擇模型精度,預設為fp32
,可選有fp16
和fp32
。fp16
推理速度更快。如果選擇fp16
,請先確保機器正確安裝NVIDIA相關驅動和基礎軟體,確保CUDA>=11.2,cuDNN>=8.1.1,初次使用需按照提示安裝相關依賴。其次,需要確保GPU裝置的CUDA計算能力(CUDA Compute Capability)大於7.0,典型的裝置包括V100、T4、A10、A100、GTX 20系列和30系列顯示卡等。更多關於CUDA Compute Capability和精度支援情況請參考NVIDIA文件:GPU硬體與支援精度對照表。- Client 自定義引數
# Changed to input texts you wanted
texts = ["中性粒細胞比率偏低"]
%cd /home/aistudio/deploy/simple_serving
!paddlenlp server server:app --workers 1 --host 0.0.0.0 --port 8190
#Error loading ASGI app. Could not import module "server".
#去終端執行即可
/home/aistudio/deploy/simple_serving
[2023-04-13 18:26:51,839] [ INFO] - starting to PaddleNLP SimpleServer...
[2023-04-13 18:26:51,840] [ INFO] - The PaddleNLP SimpleServer is starting, backend component uvicorn arguments as follows:
[2023-04-13 18:26:51,840] [ INFO] - the starting argument [host]=0.0.0.0
[2023-04-13 18:26:51,840] [ INFO] - the starting argument [port]=8190
[2023-04-13 18:26:51,840] [ INFO] - the starting argument [log_level]=None
[2023-04-13 18:26:51,840] [ INFO] - the starting argument [workers]=1
[2023-04-13 18:26:51,840] [ INFO] - the starting argument [limit_concurrency]=None
[2023-04-13 18:26:51,840] [ INFO] - the starting argument [limit_max_requests]=None
[2023-04-13 18:26:51,840] [ INFO] - the starting argument [timeout_keep_alive]=15
[2023-04-13 18:26:51,840] [ INFO] - the starting argument [app_dir]=/home/aistudio/deploy/simple_serving
[2023-04-13 18:26:51,840] [ INFO] - the starting argument [reload]=False
[2023-04-13 18:26:52,037] [ INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load 'utc-base'.
[2023-04-13 18:26:52,038] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/utc-base/utc_base_vocab.txt
[2023-04-13 18:26:52,067] [ INFO] - tokenizer config file saved in /home/aistudio/.paddlenlp/models/utc-base/tokenizer_config.json
[2023-04-13 18:26:52,067] [ INFO] - Special tokens file saved in /home/aistudio/.paddlenlp/models/utc-base/special_tokens_map.json
[2023-04-13 18:26:52,069] [ INFO] - Assigning ['[O-MASK]'] to the additional_special_tokens key of the tokenizer
[2023-04-13 18:26:55,628] [ INFO] - Taskflow request [path]=/taskflow/utc is genereated.
INFO: Started server process [1718]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8190 (Press CTRL+C to quit)
^C
INFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [1718]
在notebook如果不行,可以直接進入終端進行除錯,需要注意的是要在同一個路徑下不然會報錯
# Save at server.py
from paddlenlp import SimpleServer, Taskflow
schema = ["病情診斷", "治療方案", "病因分析", "指標解讀", "就醫建議"]
utc = Taskflow("zero_shot_text_classification",
model="utc-base",
schema=schema,
task_path="/home/aistudio/checkpoint/model_best/plm",
precision="fp32")
app = SimpleServer()
app.register_taskflow("taskflow/utc", utc)
# %cd /home/aistudio/deploy/simple_serving
!python client.py
6.總結
原專案連結:
https://blog.csdn.net/sinat_39620217/article/details/130237035
原文文末含碼源以及地址
Macro F1和Micro F1都是評估分類模型效能的指標,但是它們計算方式不同。
-
Macro F1是每個類別的F1值的平均值,不考慮類別的樣本數。它適用於資料集中各個類別的樣本數量相近的情況下,可以更好地反映每個類別的效能。
-
Micro F1是所有類別的F1值的加權平均,其中權重為每個類別的樣本數。它將所有類別的預測結果彙總為一個混淆矩陣,並計算出整個資料集的精確率、召回率和F1值。Micro F1適用於多分類問題,尤其是在資料集不平衡的情況下,可以更好地反映整體的效能。
總之,Micro F1更關注整個資料集的效能,而Macro F1更關注每個類別的效能。
醫療意圖分類資料集 KUAKE-QIC 驗證集 zero-shot 實驗指標和小樣本下訓練對比:
Macro F1 | Micro F1 | 微調後 Macro F1 | 微調後 Micro F1 | |
---|---|---|---|---|
utc-xbase | 66.30 | 89.67 | ||
utc-base | 64.13 | 89.06 | 81.67(+17.54) | 93.94 (+4.88) |
utc-medium | 69.62 | 89.15 | ||
utc-micro | 60.31 | 79.14 | ||
utc-mini | 65.82 | 89.82 | ||
utc-nano | 62.03 | 80.92 | ||
utc-pico | 53.63 | 83.57 |
6.1 更多工適配
PaddleNLP結合文心ERNIE,基於UTC技術開源了首個面向通用文字分類的產業級技術方案。對於簡單任務,透過呼叫 paddlenlp.Taskflow API ,僅用三行程式碼即可實現零樣本(Zero-shot)通用文字分類,可支援情感分析、意圖識別、語義匹配、蘊含推理等各種可轉換為分類問題的NLU任務。僅使用一個模型即可同時支援多個任務,便捷高效!
from pprint import pprint
from paddlenlp import Taskflow
# 情感分析
cls = Taskflow("zero_shot_text_classification", schema=["這是一條好評", "這是一條差評"])
cls("房間乾淨明亮,非常不錯")
>>>
[{'predictions': [{'label': '這是一條好評', 'score': 0.9695149765679986}],
'text_a': '房間乾淨明亮,非常不錯'}]
# 意圖識別
schema = ["病情診斷", "治療方案", "病因分析", "指標解讀", "就醫建議", "疾病表述", "後果表述", "注意事項", "功效作用", "醫療費用", "其他"]
pprint(cls("先天性厚甲症去哪裡治"))
>>>
[{'predictions': [{'label': '就醫建議', 'score': 0.9628814210597645}],
'text_a': '先天性厚甲症去哪裡治'}]
# 語義相似度
cls = Taskflow("zero_shot_text_classification", schema=["不同", "相同"])
pprint(cls([["怎麼檢視合同", "從哪裡可以看到合同"], ["為什麼一直沒有電話來確認借款資訊", "為何我還款了,今天卻接到客服電話通知"]]))
>>>
[{'predictions': [{'label': '相同', 'score': 0.9775065319076257}],
'text_a': '怎麼檢視合同',
'text_b': '從哪裡可以看到合同'},
{'predictions': [{'label': '不同', 'score': 0.9918983379165037}],
'text_a': '為什麼一直沒有電話來確認借款資訊',
'text_b': '為何我還款了,今天卻接到客服電話通知'}]
# 蘊含推理
cls = Taskflow("zero_shot_text_classification", schema=["中立", "蘊含", "矛盾"])
pprint(cls([["一個騎腳踏車的人正沿著一條城市街道朝一座有時鐘的塔走去。", "騎腳踏車的人正朝鐘樓走去。"],
["一個留著長髮和鬍鬚的怪人,在地鐵裡穿著一件顏色鮮豔的襯衫。", "這件襯衫是新的。"],
["一個穿著綠色襯衫的媽媽和一個穿全黑衣服的男人在跳舞。", "兩人都穿著白色褲子。"]]))
>>>
[{'predictions': [{'label': '蘊含', 'score': 0.9944843058584897}],
'text_a': '一個騎腳踏車的人正沿著一條城市街道朝一座有時鐘的塔走去。',
'text_b': '騎腳踏車的人正朝鐘樓走去。'},
{'predictions': [{'label': '中立', 'score': 0.6659998351201399}],
'text_a': '一個留著長髮和鬍鬚的怪人,在地鐵裡穿著一件顏色鮮豔的襯衫。',
'text_b': '這件襯衫是新的。'},
{'predictions': [{'label': '矛盾', 'score': 0.9270557883904931}],
'text_a': '一個穿著綠色襯衫的媽媽和一個穿全黑衣服的男人在跳舞。',
'text_b': '兩人都穿著白色褲子。'}]