二、transformers基礎組件之Tokenizer

在使用神經網絡處理自然語言處理任務時,我們首先需要對數據進行預處理,將數據從字符串轉換為神經網絡可以接受的格式,一般會分為如下幾步:

- Step1 分詞:使用分詞器對文本數據進行分詞(字、字詞);
- Step2 構建詞典:根據數據集分詞的結果,構建詞典映射(這一步并不絕對,如果采用預訓練詞向量,詞典映 射要根據詞向量文件進行處理);
- Step3 數據轉換:根據構建好的詞典,將分詞處理后的數據做映射,將文本序列轉換為數字序列;
- Step4 數據填充與截斷:在以batch輸入到模型的方式中,需要對過短的數據進行填充,過長的數據進行截斷, 保證數據長度符合模型能接受的范圍,同時batch內的數據維度大小一致。

在transformers工具包中,只需要借助Tokenizer模塊便可以快速的實現上述全部工作,它的功能就是將文本轉換為神經網絡可以處理的數據。Tokenizer工具包無需額外安裝,會隨著transformers一起安裝。

1 Tokenizer 基本使用(對單條數據進行處理)

Tokenizer 基本使用:
(1) 加載保存(from_pretrained / save_pretrained)
(2) 句子分詞(tokenize)
(3) 查看詞典 (vocab)
(4) 索引轉換(convert_tokens_to_ids / convert_ids_to_tokens)
(5) 填充截斷(padding / truncation)
(6) 其他輸入(attention_mask / token_type_ids)

不同的模型會對應不同的tokenizer。transformers中需要導入AutoTokenizer,AutoTokenizer會根據不同的模型導入對應的tokenizer

1.1. Tokenizer的加載與保存

from transformers import AutoTokenizer
# 從HuggingFace加載,輸入模型名稱,即可加載對于的分詞器
tokenizer = AutoTokenizer.from_pretrained("../models/roberta-base-finetuned-dianping-chinese")

tokenizer打印結果如下:

BertTokenizerFast(name_or_path='/root/autodl-fs/models/roberta-base-finetuned-dianping-chinese', vocab_size=21128, model_max_length=1000000000000000019884624838656, is_fast=True, padding_side='right', truncation_side='right', 
special_tokens={'unk_token': '[UNK]', 'sep_token': '[SEP]', 'pad_token': '[PAD]', 'cls_token': '[CLS]', 'mask_token': '[MASK]'}, clean_up_tokenization_spaces=True),  added_tokens_decoder={0: AddedToken("[PAD]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),100: AddedToken("[UNK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),101: AddedToken("[CLS]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),102: AddedToken("[SEP]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),103: AddedToken("[MASK]", rstrip=False, lstrip=False, single_word=False, normalized=False, special=True),
}

將tokenizer 保存到本地后可以直接從本地加載

# tokenizer 保存到本地
tokenizer.save_pretrained("./roberta_tokenizer")
# 從本地加載tokenizer
tokenizer = AutoTokenizer.from_pretrained("./roberta_tokenizer/")

1.2. 句子分詞

sen = "弱小的我也有大夢想!"
tokens = tokenizer.tokenize(sen)
#['弱', '小', '的', '我', '也', '有', '大', '夢', '想', '!']

1.3. 查看字典

tokenizer.vocab
tokenizer.vocab_size  #21128
{'##椪': 16551,'##瀅': 17157,'##蝕': 19128,'##魅': 20848,'##隱': 20460,'儆': 1024,'嫣': 2073,'簧': 5082,'鎂': 7250,'maggie': 12423,'768': 12472,'1921': 10033,'焜': 4191,'瀆': 3932,'鎂': 7110,'謚': 6471,'app': 8172,'噱': 1694,'goo': 9271,'345': 11434,'##rin': 13250,'?': 324,'redis': 12599,'/': 8027,'蒞': 5797,
...'##轟': 19821,'387': 12716,'##齣': 21031,'##ント': 10002,...}
Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...

1.4. 索引轉換

# 將詞序列轉換為id序列
ids = tokenizer.convert_tokens_to_ids(tokens)
#[2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106]# 將id序列轉換為token序列
tokens = tokenizer.convert_ids_to_tokens(ids)
#['弱', '小', '的', '我', '也', '有', '大', '夢', '想', '!']# 將token序列轉換為string
str_sen = tokenizer.convert_tokens_to_string(tokens)
#'弱 小 的 我 也 有 大 夢 想!'

上面的把各個步驟都分開了,簡潔的方法:

# 將字符串轉換為id序列,又稱之為編碼
ids = tokenizer.encode(sen, add_special_tokens=True)
# [101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106, 102]# 將id序列轉換為字符串,又稱之為解碼
str_sen = tokenizer.decode(ids, skip_special_tokens=False)
# '[CLS] 弱 小 的 我 也 有 大 夢 想! [SEP]'

下面的方法比上面多了兩個special_tokens:[CLS][SEP],這是特定tokenizer給定的,句子開頭和句子結尾

1.5. 填充與截斷

以上是針對單條數據,如果是針對多條數據會涉及到填充和截斷。把短的數據補齊,長的數據截斷。

# 填充
ids = tokenizer.encode(sen, padding="max_length", max_length=15)
# [101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106, 102, 0, 0, 0]
# 截斷
ids = tokenizer.encode(sen, max_length=5, truncation=True)
# [101, 2483, 2207, 4638, 102]

填充和階段的長度包含了兩個special_tokens:[CLS][SEP]

1.6. 其他輸入部分

數據處理里面還有一個地方要特別注意:既然數據中存在著填充,就要告訴模型,哪些是填充,哪些是有效的數據。這個時候需要attention_mask。也就是說,對于上面的例子,ids為0的元素對應的attention_mask的元素應為0,不為0的元素位置attention_mask的元素應為0。
另外香BERT這樣的模型需要token_type_ids標定是第幾個句子。

1.6.1 手動生成方式(體現定義)

如果是手動設定attention_mask和token_type_ids如下:

attention_mask = [1 if idx != 0 else 0 for idx in ids]
token_type_ids = [0] * len(ids)
#ids:   ([101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106, 102, 0, 0, 0],
#attention_mask:  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
#token_type_ids:  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
1.6.2 快速調用方式

transformers肯定不會讓手動生成,有自動的方法。就是encode_plus

inputs = tokenizer.encode_plus(sen, padding="max_length", max_length=15)

使用encode_plus生成的是一個字典如下:

{
'input_ids': [101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106, 102, 0, 0, 0], 
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]
}

‘input_ids’:分此后轉換的id
‘token_type_ids’:屬于第幾個句子
‘attention_mask’:1對應的’input_ids’元素是非填充元素,是真實有效的

調用encode_plus方法名字太長了,不好記,等效的方法就是可以直接用 tokenizer而不使用任何方法

inputs = tokenizer(sen, padding="max_length", max_length=15)

得到和上面一樣的結果:

{
'input_ids': [101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 106, 102, 0, 0, 0], 
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]
}

2 處理batch數據

上面是處理單條數據,現在看看怎么處理batch數據

sens = ["弱小的我也有大夢想","有夢想誰都了不起","追逐夢想的心,比夢想本身,更可貴"]
res = tokenizer(sens)
#{'input_ids': [[101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 3457, 2682, 102], [101, 3300, 3457, 2682, 6443, 6963, 749, 679, 6629, 102], [101, 6841, 6852, 3457, 2682, 4638, 2552, 8024, 3683, 3457, 2682, 3315, 6716, 8024, 3291, 1377, 6586, 102]], 'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]}

sens是個列表有3個句子,得到的res是一個字典,包含:‘input_ids’;‘token_type_ids’;‘attention_mask’,每個都是一個列表,列表的每個元素對應每個句子’input_ids’;‘token_type_ids’;‘attention_mask’

以batch的方式去處理比一個一個的處理速度更快。

3 Fast/Slow Tokenizer

Tokenizer有快的版本和慢的版本

3.1 FastTokenizer

  • 基于Rust實現,速度快
  • offsets_mapping、 word_ids SlowTokenizer
sen = "弱小的我也有大Dreaming!"
fast_tokenizer = AutoTokenizer.from_pretrained(model_path)

請添加圖片描述

FastTokenizer會有一些特殊的返回。比如return_offsets_mapping,用來指示每個token對應到原文的起始位置。

inputs = fast_tokenizer(sen, return_offsets_mapping=True)
{'input_ids': [101, 2483, 2207, 4638, 2769, 738, 3300, 1920, 10252, 8221, 106, 102], 
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], # "弱小的我也有大Dreaming!"
# Dreaming被分為兩個詞(7, 12), (12, 15)
# 該字段中保存著每個token對應到原文中的起始與結束位置
'offset_mapping': [(0, 0), (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 12), (12, 15), (15, 16), (0, 0)]
}
# word_ids方法,該方法會返回分詞后token序列對應原始實際詞的索引,特殊標記的值為None。
# Dreaming被分為兩個詞【7, 7】
inputs.word_ids()
# [None, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, None]

3.2 SlowTokenizer

  • 基于Python實現,速度慢
slow_tokenizer = AutoTokenizer.from_pretrained(model_path, use_fast=False)

請添加圖片描述兩種方式的時間對比如下:

請添加圖片描述

4 特殊Tokenizer的加載

一些非官方實現的模型,自己實現了tokenizer,如果想用他們自己實現的tokenizer,需要指定trust_remote_code=True

from transformers import AutoTokenizer# 需要設置trust_remote_code=True
# 表示信任遠程代碼
tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True)
tokenizer

即使保存到本地,然后從本地加載也要設置trust_remote_code=True

tokenizer.save_pretrained("chatglm_tokenizer")# 需要設置trust_remote_code=True
tokenizer = AutoTokenizer.from_pretrained("chatglm_tokenizer", trust_remote_code=True)

參考鏈接:【手把手帶你實戰HuggingFace Transformers-入門篇】基礎組件之Tokenizer_嗶哩嗶哩_bilibili

Transformers基本組件(一)快速入門Pipeline、Tokenizer、Model_transformers.pipeline-CSDN博客

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/905058.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/905058.shtml
英文地址,請注明出處:http://en.pswp.cn/news/905058.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鏡像和容器的管理

一、鏡像的管理 獲取鏡像并生成相關容器 # 拉取鏡像 docker pull alpine # 默認是latest,也就是最新版本,也可指定版本(在鏡像名后邊加“:版本號”) # 或者 # 從主機中導入鏡像到docker中 docker image load -i /test#生成容器 …

設計模式簡述(十九)橋梁模式

橋梁模式 描述基本組件使用 描述 橋梁模式是一種相對簡單的模式,通常以組合替代繼承的方式實現。 從設計原則來講,可以說是單一職責的一種體現。 將原本在一個類中的功能,按更細的粒度拆分到不同的類中,然后各自獨立發展。 基本…

ImportError: DLL load failed: 找不到指定的程序。

查看其他博客說是缺少libssl-1_1-x64.dll 和 libcrypto-1_1-x64.dll 然后去下載放到博客說的目錄下 沒有用 解決不了一點 OpenSSL for Windows 64位 完整安裝包 在這里 項目地址: https://gitcode.com/open-source-toolkit/eb627 注意事項 此安裝包僅適用于64位Windows系…

電池單元和電極性能

電芯設計中的挑戰 對于電池制造商來說,提高電池能量和功率密度至關重要。在高功率密度和長循環壽命之間取得平衡是電池設計中的關鍵挑戰,通常需要仔細優化材料、電極結構和熱管理系統。另一個關鍵挑戰是通過優化重量體積比來降低電池單元的總體成本。 工…

數據加密與隱私保護:讓你的信息固若金湯

數據加密與隱私保護:讓你的信息固若金湯 大家好,我是 Echo_Wish,今天聊聊一個 人人都關心、但很多人沒做好 的話題——數據加密與隱私保護的最佳實踐。 為什么要重視數據安全? 現在是數字化時代,從個人照片、銀行卡信息到企業機密,數據泄露的風險無處不在。你可能覺得自…

【高數上冊筆記篇02】:數列與函數極限

【參考資料】 同濟大學《高等數學》教材樊順厚老師B站《高等數學精講》系列課程 (注:本筆記為個人數學復習資料,旨在通過系統化整理替代厚重教材,便于隨時查閱與鞏固知識要點) 僅用于個人數學復習,因為課…

C++(8):類型限定符

目錄 1. const:定義常量 2. volatile:易變性修飾 3. restrict(C非標準) 4. mutable:突破常量性 5. static:靜態存儲 6. register(已棄用) 分類修正說明 1. const:…

Nginx yum 安裝

一、環境準備 一臺裝有 CentOS 7.9 的虛擬機 二、安裝 安裝 yum install -y nginx -y:所有的安裝選項都選擇 yes。 啟動 nginx systemctl enable nginx --now enable:設置 nginx 為開機啟動。--now:馬上啟動 nginx。 查看 nginx 服務狀態…

【5分鐘學Docker】Docker快速使用

目錄 1. 概述 2. 基本操作 2.1. 鏡像操作 2.2. 容器操作 2.3. 運行操作 2.4. 鏡像保存 2.5. 鏡像分享 3. 高級操作 4. 掛載 4.1. 目錄掛載 4.2. 卷映射 1. 概述 Docker 鏡像有鏡像名稱和TAG 2. 基本操作 2.1. 鏡像操作 查看鏡像 docker images docker image ls …

5000字總結 HTML5 中的音頻和視頻,關羽標簽、屬性、API 和最佳實踐

HTML5 音頻與視頻開發完全指南&#xff1a;標簽、屬性、API 與最佳實踐 一、引言&#xff1a;HTML5 媒體時代的到來 在 HTML5 之前&#xff0c;網頁中的音頻和視頻播放依賴 Flash、Silverlight 等第三方插件&#xff0c;存在兼容性差、性能瓶頸和安全隱患。HTML5 引入的 <…

【C語言】(9)—指針3

文章目錄 一、字符指針的深入理解二、數組指針詳解三、二維數組傳參的本質四、函數指針及其應用五、函數指針數組與轉移表 一、字符指針的深入理解 1.1 字符指針的基本使用 字符指針(char*)是指向字符類型數據的指針&#xff0c;它有兩種常見的使用方式&#xff1a; // 方式一…

MDK調試技巧

1、自動生成反匯編 fromelf -c -o "$LL.txt" "#L" 解釋&#xff1a; 1、fromelf 是 ARM Compiler 工具鏈中的一個命令行工具&#xff0c;從fromelf這個名字上我們就能看到它是用來處理elf文件的&#xff0c;elf 全稱 Executable and Linking Format &…

嵌入式STM32學習——433M無線遙控燈

1.433M無限模塊工作原理&#xff1a; 數據發射模塊的工作頻率為315M&#xff0c;采用聲表諧振器SAW穩頻&#xff0c;頻率穩定度極高&#xff0c;當環境溫度在-25~85度之間變化時&#xff0c;頻飄僅為3ppm。 接收到信號&#xff0c;接收模塊對應針腳輸出高電平&#xff0c;有DO…

JDBC工具類的三個版本

一、JDBC連接數據庫的7個步驟 1、加載驅動 2、獲取連接 3、編寫sql 4、獲取執行sql的stmt對象 有兩種 stmt&#xff08;存在sql注入問題 字符串拼接&#xff09; pstmt&#xff08;預編譯可以防止sql注入&#xff09; 5、執行sql 拿到結果集 6、遍歷結果集 7、關閉資源…

3.1/Q1,Charls最新文章解讀

文章題目&#xff1a;Predictive model for sarcopenia in chronic kidney disease: a nomogram and machine learning approach using CHARLS data DOI&#xff1a;10.3389/fmed.2025.1546988 中文標題&#xff1a;慢性腎病肌肉減少癥的預測模型&#xff1a;使用 CHARLS 數據的…

DEEPPOLAR:通過深度學習發明非線性大核極坐標碼(2)

目錄 2.問題的提出和背景 2.1 信道編碼 2.2.極化碼 極坐標編碼 極坐標解碼 原文&#xff1a;《DEEPPOLAR: Inventing Nonlinear Large-Kernel Polar Codes via Deep Learning》 2.問題的提出和背景 2.1 信道編碼 信道編碼是一種為傳輸添加冗余的技術&#xff0c;使其對…

手機當電腦播放器 soundwire

soundwire server免費下載_soundwire serverPC下載_3DM軟件 win11可用延遲1秒 安卓端音頻緩沖區大小改成8k延遲就沒那么夸張了 我用audiorelay連上了沒聲音

LVGL中的事件

文章目錄 &#x1f9f1; 一、什么是 LVGL 事件&#xff1f;&#x1f3af; 二、事件回調的注冊參數解釋&#xff1a;示例&#xff1a; &#x1f4da; 三、常見事件類型&#xff08;lv_event_code_t&#xff09;? 1. 輸入類事件&#xff08;用戶交互&#xff09;? 2. 組件狀態類…

警惕C#版本差異多線程中的foreach陷阱

警惕C#版本差異多線程中的foreach陷阱? 同樣的代碼,不同的結果閉包捕獲的“時間差”問題繞過閉包陷阱的三種方法Lambda立即捕獲(代碼簡潔)顯式傳遞參數(兼容性最佳)使用Parallel.ForEach(官方推薦)注意事項:版本兼容性指南警惕多線程中的foreach陷阱:C#版本差異引發的…

mac u盤重裝mac10.15Catalina系統

我的電腦提mac2017的air 重裝過程 (文件夾中間有空格時為 Install\ macOS\ Catalina 才行) &#xff08;有需要的&#xff0c;最好做一下備份&#xff0c;有些東西可以及時找到配置和文件之類的&#xff0c; u盤制作是在mac電腦上操作的) 一、先下載系統鏡像文件或自行到官方…