AI-LECTURER 速報課|2026-07-23|約 26 分鐘

分詞快到飛起:GigaToken 如何把文字前處理的等待時間壓到眨眼之間

取材:GigaToken: ~1000x faster Language model tokenization(Hacker News(AI 高人氣))
📍 真實場景
阿凱,新創公司裡負責 RAG 聊天機器人的後端工程師

他要把公司裡上萬份內部 PDF 文件轉成模型看得懂的格式,先做前處理,再餵進向量資料庫

😖 卡住的地方:光是把文字切成模型看得懂的小塊這一步,就要在自己的筆電上跑好幾個小時;每次改一次 prompt 模板的規則,就得整批重跑一次,進度卡住,主管一直在群組裡問進度
💡 這課會讓阿凱發現,原來『分詞』這個看似基礎的步驟,本身就可能是效能瓶頸,而且有工具能幾乎不改程式碼就把它加速到近乎不用等

🧭 這到底是什麼(白話版)

在語言模型能讀懂一段文字之前,電腦得先做一件事:把這段文字切成一小塊一小塊、模型看得懂的單位,這個步驟叫 tokenization(分詞)把一整段文字拆成模型看得懂的小塊,例如把「我愛AI」拆成「我」「愛」「AI」三小塊,拆出來的每一小塊就叫做 token分詞後的最小單位,語言模型讀文字其實是一塊一塊讀,不是一個字一個字讀。這一步聽起來很基礎,但只要要處理的文字資料量夠大,它就可能變成整條處理流程裡最花時間的一關。

GigaToken 就是專門解決這個瓶頸的一款分詞工具。它最大的賣點是 drop-in replacement(直接替換)不用改動任何呼叫端程式碼,只要把舊的分詞工具換成新工具,其他地方完全不動,也就是說,原本用 HuggingFace 或 OpenAI 的 tiktoken 在跑分詞的程式,幾乎不用改,就能把底層引擎換成 GigaToken。

它能快這麼多,靠的不是什麼魔法,而是紮實的工程功夫:底層用 Rust一種以「快又安全」聞名的程式語言,許多要求極致效能的底層工具都用它寫 實作,並且用 多執行緒(multithreaded)讓程式同時動用電腦裡好幾顆處理器核心一起工作,而不是一次只用一顆 把工作平行分散到所有核心上;它甚至還提供一套原生 API(應用程式介面)一套「你呼叫我、我回你」的固定溝通規則,讓不同程式之間可以互相合作,讓 Rust 直接讀取檔案,省掉跟 Python 來回搬資料的成本。

官方的 benchmark 用 吞吐量(throughput)衡量「單位時間內能處理多少資料量」的指標,這裡用 GB/s,也就是每秒能吃下幾十億位元組的文字 來呈現差距:同樣一份將近 12 GB 的文字資料,HuggingFace 的分詞器一秒只能啃幾十 MB,GigaToken 卻能一秒啃掉超過 20 GB,等於把等待時間從『泡杯咖啡』壓縮到『眨個眼』。

🎯 為什麼值得你花時間

省下來的是真金白銀的等待時間處理幾十 GB 等級的文字資料,從按 MB/s 計算的等待,變成按 GB/s 計算,等待時間從好幾個小時掉到幾秒鐘,對每天都要重跑資料前處理的工程師來說是巨大的生產力差異。
輸出結果要跟原本工具一模一樣,才敢放心換很多加速工具最後的輸出會跟原本工具有細微差異,導致模型效果跑掉;GigaToken 特別強調『相容模式』下輸出與 HuggingFace 分詞器完全一致,代表你能放心替換底層引擎,不用重新驗證模型效果。
提醒我們:效能瓶頸不一定在你以為的地方大家常把最佳化力氣花在模型本身,例如換更快的 GPU;這次事件提醒我們,前處理的分詞步驟本身也可能是被忽視的效能瓶頸,值得被同等重視。

⚙️ 它是怎麼運作的

1
文字進來,先被切成模型看得懂的小塊不管用哪個分詞工具,第一步都是把整段文字拆成一個一個 token,這是餵給語言模型之前必經的前處理步驟。
2
GigaToken 用 Rust 底層加多執行緒平行處理同樣是拆文字,GigaToken 用效能取向的程式語言寫核心邏輯,再把工作平均分給電腦裡所有處理器核心一起做,而不是排隊一個一個做。
3
兩種使用模式:相容模式 vs 原生模式相容模式(as_hf/as_tiktoken)咬死要跟舊工具輸出一模一樣,速度快很多但沒到極限;原生 API 模式讓 Rust 直接讀檔案、跳過 Python 端的搬運開銷,速度衝到接近 1000 倍。
4
用真實資料集攤開 benchmark 讓大家檢驗作者用 11.9 GB 的真實文字資料集,在 144 核心的伺服器上,對十幾種主流模型的分詞器分別測試,把 GB/s 對 MB/s 的落差攤在陽光下,讓數字說話而不是喊口號。
同一份 11.9 GB 文字資料,不同分詞器的處理速度(AMD EPYC 9565 72核心 x2)
模型GigaToken 速度HuggingFace tokenizers 速度比 HF 快幾倍
GPT-224.53 GB/s24.8 MB/s989×
Llama 3 / 3.1 / 3.222.15 GB/s48.5 MB/s457×
Qwen 322.16 GB/s34.2 MB/s648×
DeepSeek V3 / R1 / V419.69 GB/s26.2 MB/s750×

🔍 程式碼漫遊(點有 ● 的行看白話講解)

這段程式示範怎麼把現有的 HuggingFace 分詞器,幾乎不改呼叫方式地換成 GigaToken 的相容模式

import gigatoken as gt
💬 先把 gigatoken 這個套件匯入進來,取個好打的別名 gt。
hf_tokenizer = AutoTokenizer.from_pretrained('gpt2')
💬 沿用你原本就在用的 HuggingFace 分詞器,這一行完全不用改。
tokenizer = gt.Tokenizer(hf_tokenizer).as_hf()
💬 重點在這一行:把舊分詞器包進 GigaToken,並用 as_hf() 開啟『相容模式』,讓輸出格式跟原本一模一樣。
tokens = tokenizer.encode_batch(['This is a test string', 'And here is another'])
💬 呼叫方式跟原本的 HuggingFace 分詞器一樣,下游程式碼完全不用改。
print(len(tokens[0]), len(tokens[1]))
💬 確認分出來的 token 數量跟原本工具比對是否一致,這就是在驗證『真的可以直接替換』。

🛠️ 動手做:動手把 GigaToken 裝起來,實際比一次分詞速度

這是一個真實小專案:下載(或複製)檔案,照步驟在你電腦上跑起來。

📄 compare_speed.py ⬇ 下載
# 比較 HuggingFace 分詞器與 GigaToken 相容模式的處理速度
import time
from pathlib import Path
from transformers import AutoTokenizer
import gigatoken as gt

SAMPLE_TEXT_PATH = Path('sample.txt')


def load_sample_text():
    if not SAMPLE_TEXT_PATH.exists():
        SAMPLE_TEXT_PATH.write_text('這是一段測試文字。' * 50000, encoding='utf-8')
    return SAMPLE_TEXT_PATH.read_text(encoding='utf-8')


def time_tokenizer(name, encode_fn, text):
    start = time.perf_counter()
    tokens = encode_fn([text])
    elapsed = time.perf_counter() - start
    token_count = len(tokens[0]) if tokens else 0
    print(f'{name}:{elapsed:.3f} 秒,共 {token_count} 個 token')


def main():
    text = load_sample_text()

    hf_tokenizer = AutoTokenizer.from_pretrained('gpt2')
    time_tokenizer(
        'HuggingFace tokenizers',
        lambda batch: [hf_tokenizer.encode(t) for t in batch],
        text,
    )

    gigatoken_tokenizer = gt.Tokenizer(hf_tokenizer).as_hf()
    time_tokenizer(
        'GigaToken(相容模式)',
        gigatoken_tokenizer.encode_batch,
        text,
    )


if __name__ == '__main__':
    main()
  1. 開啟 PowerShell,建立一個新資料夾放這個小專案,例如:cd D:\practice\gigatoken-demo
  2. 建立虛擬環境:python -m venv .venv
  3. 啟用虛擬環境:.venv\Scripts\Activate.ps1
  4. 安裝需要的套件:pip install gigatoken transformers
  5. 把上面的 compare_speed.py 存到這個資料夾裡
  6. 執行看看:python compare_speed.py
  7. 比較兩行印出來的秒數,感受一下『相容模式』下的速度差距(如果你的電腦核心數不多,差距不會有官方 benchmark 那麼誇張,這是正常現象)

🧠 工程思維透鏡(資深工程師看到的是什麼)

🔭 為什麼作者要特別做『相容模式』,多做這層還犧牲一點效能,值得嗎?
純新 API 最快但需要改寫呼叫方式,有遷移成本;相容模式速度略降但幾乎零遷移成本,對已經有大量現成 pipeline 的團隊來說,『不用改程式碼』的價值可能比『多幾倍速度』更重要。這是產品設計上『犧牲一點理論最大效能,換取採用門檻趨近於零』的經典取捨。
🔭 為什麼要斤斤計較『輸出結果要跟原本工具一模一樣』?
分詞結果只要跟原本有一點點不同,即使是極少數 edge case,都可能讓下游模型的行為跟著改變,因為模型是根據 token id 訓練出來的,這種差異會造成難以追蹤的品質退化。所以『正確性優先於效能』是工程上正確的排序:速度永遠可以再優化,正確性一旦妥協,debug 成本會非常高。
🔭 為什麼要特別強調『對手本身就已經是多執行緒的 Rust 實作』?
這是在替自己的成果做誠實的天花板管理——先承認對手不是省油的燈,不是輸在單執行緒或用慢語言寫,藉此凸顯自己的優勢不是來自這些基本功,而是來自架構設計本身。這種先自我對照基準線的誠實揭露,反而讓效能數字更有說服力,也更經得起檢驗。
🔭 為什麼原生 API 模式要讓 Rust 直接讀檔案,而不是先在 Python 讀進來再丟給 Rust?
這是在處理跨語言呼叫的搬運成本——Python 與 Rust 之間傳遞資料,本質上要經過物件建立、轉換與複製,資料量越大這個開銷越明顯。讓 Rust 直接負責 I/O,可以完全略過 Python 端的中間物件,這是效能工程裡常見的『減少跨邊界資料搬運』設計原則。

📝 隨堂考(點選答案,立即回饋)

Q1. GigaToken 宣稱最接近 1000 倍的速度優勢,主要是在哪一種使用情境下量出來的?
✅ 文中提到相容模式雖然快很多,但為了對齊原本輸出格式犧牲了一些效能;真正逼近 1000x 的是使用 GigaToken 原生 API,讓 Rust 直接讀檔案的情境。
Q2. 文中的 benchmark 用什麼單位來呈現分詞速度?
✅ benchmark 表格用 GB/s 或 MB/s 表示分詞吞吐量,這樣才能公平比較不同工具處理同一份資料的速度。
Q3. 為什麼作者要特地說明 HuggingFace tokenizers 和 tiktoken『本來就是多執行緒的 Rust 實作』?
✅ 文中特別強調 HF tokenizers 和 tiktoken 本身已經是多執行緒的 Rust 實作,讀者才會知道 GigaToken 的優勢不是贏在『對手很爛』,而是架構設計真的更有效率。
Q4. 『drop-in replacement(直接替換)』在這篇素材中的意思最接近下列哪一個?
✅ drop-in replacement 的重點就是『呼叫端幾乎不用改』,這也是為什麼相容模式對已經上線的舊系統特別有吸引力。
Q5. 如果你的系統目前用 tiktoken 處理好幾十 GB 的訓練語料,分詞這一步跑很久,根據這篇素材,最合理的做法是?
✅ 分詞是 CPU 密集的前處理步驟,跟 GPU 沒有直接關係;務實的做法是先在小樣本驗證輸出是否一致,確認沒問題後再全量替換,兼顧速度與正確性。

🃏 翻牌記憶卡(先想答案,再點開對答)

什麼是 tokenization(分詞)?點我翻面
把整段文字切成模型看得懂的小塊(token)的前處理步驟。
GigaToken 的『相容模式』是什麼?點我翻面
用 as_hf() 或 as_tiktoken() 包裝,輸出結果對齊原本工具,速度比原生 API 略慢一些。
GigaToken 為什麼比舊工具快這麼多?點我翻面
底層用 Rust 實作加多執行緒平行處理,原生 API 還能讓 Rust 直接讀檔案,跳過 Python 資料搬運的開銷。
什麼是 drop-in replacement(直接替換)?點我翻面
不用改動呼叫端程式碼,把舊工具換掉就能用的相容設計。
GB/s 在這篇素材代表什麼?點我翻面
衡量分詞吞吐量的單位,每秒能處理幾十億位元組的原始文字。

✅ 離開前自測(全勾=這課真的學會了)

0%