iT邦幫忙

2025 iThome 鐵人賽

DAY 5
0
佛心分享-IT 人自學之術

學習 LLM系列 第 5

Day 5 了解 Tokenizer

  • 分享至 

  • xImage
  •  
  • okenizer : 就是把文字轉換成模型可處理的 token,也能將 token 轉回文字
  • Tokenizer 的設計會影響:
    • token 的長度
    • 是否能較好處理未見詞(OOV)
    • 對中文/英文的分詞方式
  • 三種常見方法 :
    • BPE(Byte Pair Encoding):
      • 概念:從字元或 byte 開始,反覆合併出現頻率最高的一對成為新 token
      • 特點:能形成 subword(子詞),對英文常見,GPT-2 用的是 byte-level BPE
      • 針對中文:如果是 byte-level BPE,中文常會被切成很多 byte/小片段,看起來較不直觀,但能處理各種字元
    • WordPiece
      • 概念:類似 BPE,但合併時考量不同的機率/準則(最初在 BERT 被採用)
      • 特點:常把常見詞當成 token,罕見詞拆成子詞(subword),BERT 的中文版本(如 bert-base-chinese)通常會把中文字當作最小 token(很多情況是「字級」token)
      • 對中文:結果通常會以「字」為單位(每個中文字一個 token),對分類任務好用
    • SentencePiece(Unigram / BPE 實作)
      • 概念:把整段文字當成一串字符訓練模型(不用依賴空格),會輸出帶有特殊前綴(像_)的 subword,常用在多語模型(XLM-R、T5/mt5)
      • 對中文:非常適合沒有空格的語言(中文、日文),token 中會帶 _(代表單詞邊界)或直接是中文字/子詞
  • 實驗 : 把一句中文切成 token
!pip install -q transformers sentencepiece

from transformers import AutoTokenizer

sentence = "從前從前,有一位勇敢的少年,他夢想環遊世界。"
models = {
    "GPT-2 (byte-level BPE)": "gpt2",
    "BERT Chinese (WordPiece)": "bert-base-chinese",
    "XLM-RoBERTa (SentencePiece)": "xlm-roberta-base"
}

for name, model_name in models.items():
    print("======================================")
    print(f"Model / Tokenizer: {name}  (repo: {model_name})")
    print("--------------------------------------")
    # use_fast=True 以便使用 offset mapping(若某些 tokenizer 沒有 fast 版本會退回)
    tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True)

    # 1) tokens(可讀的 subword)
    tokens = tokenizer.tokenize(sentence)
    print("tokens:", tokens)

    # 2) token ids(模型輸入要的整數 id)
    ids = tokenizer.encode(sentence, add_special_tokens=False)
    print("token ids:", ids)
    print("token count:", len(ids))

    # 3) 把 token ids decode 回文字(看看 decode 與原句是否一致)
    decoded = tokenizer.decode(ids, skip_special_tokens=True)
    print("decoded back:", decoded)

    # 4) offsets:每個 token 在原始字串的 (start, end) byte/char index(需 use_fast=True)
    enc = tokenizer(sentence, return_offsets_mapping=True, add_special_tokens=False)
    offsets = enc["offset_mapping"]
    print("\nToken -> substring mapping (token, (start,end), original substring):")
    for tok, (s, e) in zip(tokens, offsets):
        # 注意:s,e 是字元/byte index(fast tokenizer 回傳的是字符索引),我們用 slice 取原句
        subs = sentence[s:e]
        print(f"{tok:20}  ->  ({s},{e})  '{subs}'")
    print("\n")

  • AutoTokenize 是 hugging face transformers 套件提供的自動化工廠類別,給一個模型名稱,會自動下載並回傳適合的 tokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese") 不用記哪個是最適合的 tokenizer,輸入模型名稱會自動下載並回傳

  • "GPT-2 (byte-level BPE)": "gpt2" 是 key : value 的寫法

  • for name, model_name in models.items():

    • models.item() 會回傳字典所有鍵值對的序列,每個元素都是(key,value)
    • 逐一取出 models.item() 裡的每一個(key,value)
    • name, model_name 是 tuple unpacking(將資料指派給多個變數),把第一個值放進 name,第二個值放進 model_name
  • print(f"Model / Tokenizer: {name} (repo: {model_name})") 是 f-string : 在字串前面加 f ,可以在字串內使用{}來插入變數或運算結果

  • use_fast=True : 想載入 fast tokenizer 用 Rust(通用、編譯型的系統程式語言) 實作

    • fast tokenizer 能回傳 offest_mapping(紀錄字串轉換成數字時,這些數字所代表的原始文字在原始字串中的起始與結束位置)
  • tokenizer.tokenize(sentence) : 把 sentence 轉成可讀的 subword,回傳的是一個 list,每個值都是 token 字串形式

  • tokenizer.encode(sentence, add_special_tokens=False) :

    • 把 sentence 轉成模型所需要的整數 ID串 (每個 token 都有對應的整數)
  • add_special_tokens=False : 不要自動加特殊 token

  • ids 是 list

  • len(ids) 是 token 的數量

  • okenizer.decode(ids, skip_special_tokens=True) : 把整數 id 再轉回字串

    • skip_special_tokens=True : 如果有特殊 token 就跳過
    • 確定 encode ->decode 的可逆性
  • enc = tokenizer(sentence, return_offsets_mapping=True, add_special_tokens=False)

    • 把 tokenizer 當函數呼叫,回傳一個 dict
    • return_offsets_mapping=True : 告訴 tokenizer 一併回傳
    • add_special_tokens=False : 不要加上特殊 token
  • offsets = enc["offset_mapping"]

    • enc 是 dict
    • offset_mapping 是 enc 裡面的 key
    • offsets 是 list
  • for tok, (s, e) in zip(tokens, offsets):

    • 把 token 放到 tok,把 offest 拆成 s(start) 跟 e(end)
    • zip(tokens, offsets) 把 token 與 offsets 配對成 tuple
  • subs = sentence[s:e] : 取得雲劇中從 index s 到 e-1的子字串,可以驗證 tok 與原句的對應段落是否一致

  • 結果
    https://ithelp.ithome.com.tw/upload/images/20250919/20169173n9s6iH1J7s.png

https://ithelp.ithome.com.tw/upload/images/20250919/20169173a7zoiKZQXx.png


上一篇
Day4 文本生成
下一篇
Day 6 了解詞向量與嵌入
系列文
學習 LLM8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言