Perplexity AI 開源Unigram分詞器,p50延遲比Hugging Face tokenizers crate低5倍
Perplexity AI 開源了用Rust重寫的Unigram分詞器,實現了比Hugging Face tokenizers crate低5倍的p50延遲,並將生產環境CPU利用率降低了5-6倍。最佳化包括雙陣列trie、點陣圖打包和大頁面支援。
文章情報
要點
- Perplexity AI 用Rust重寫了Unigram分詞器,p50延遲比Hugging Face tokenizers crate降低5倍。
- 三項最佳化:雙陣列trie、點陣圖和快取行打包、大頁面支援。
- 生產環境CPU利用率降低5-6倍,熱路徑零堆分配。
為什麼重要
這條新聞值得關注,因為Perplexity AI 用Rust重寫了Unigram分詞器,p50延遲比Hugging Face tokenizers crate降低5倍。
技術影響
可能影響模型選型、推理成本、產品能力和評測基準。
Perplexity AI 的研究團隊用Rust從頭實現了Unigram分詞器,並將其開源在pplx-garden(推理技術倉庫)中。該分詞器針對XLM-RoBERTa模型(使用SentencePiece訓練的25萬token Unigram詞彙表)進行最佳化。
在生產輸入長度下,新編碼器的p50延遲比Hugging Face tokenizers crate低約5倍,比SentencePiece(C++)低約2倍,比IREE分詞器(C)低約1.5倍,且熱路徑無堆分配。在生產中,Perplexity推理棧的CPU利用率降低了5-6倍,重排序器延遲減少了數十毫秒。
為什麼分詞成為瓶頸
LLM推理成本通常圍繞GPU工作,但小型模型(如嵌入模型、分類器和重排序器)則不同。這些模型比前沿transformer小兩到三個數量級。重排序器每請求需對數百個候選文件評分,GPU計算常在個位數毫秒內完成,但每次輸入都需先經過CPU端分詞。當批次較大時,分詞成為總延遲的重要部分。
什麼是Unigram分詞
Unigram分詞由Kudo於2018年提出,在SentencePiece中實現。它將分詞視為最大機率路徑問題:每個詞彙token有學習到的對數機率,分詞器選擇token分數總和最高的分割。該演算法使用Viterbi演算法(1967年的動態規劃技術),其中位元組位置為圖層級,詞彙token為邊。內層迴圈在每個位元組位置遍歷詞彙trie(字首樹)。在16K token輸入上,內層遍歷執行數十萬次trie轉換,是熱路徑。
Hugging Face實現的瓶頸
在514 token(512+BOS/EOS)輸入下,Hugging Face tokenizers crate存在三個昂貴模式:每匹配一次就進行String::from_utf8和AHashMap查詢(514 token時分配7,295次);每個位元組步驟在trie節點進行AHashMap指標追蹤(4次依賴載入);長輸入時L2快取抖動(分配DP表和輸出緩衝區)。每token分配約2 KB和18次分配,在長輸入時累積溢位L2快取。
三項最佳化
**最佳化1:雙陣列trie** 將Hugging Face的HashMap trie替換為雙陣列trie(Aoe, 1989)。該結構將整個trie編碼為兩個平面整數陣列base和check。子節點查詢:next = base[node] + byte,驗證check[next] == node。只需兩次陣列讀取、一次整數加法和一次比較,無需雜湊和指標追蹤。25萬詞彙trie佔用約9 MB連續記憶體,每次編碼的熱工作集約100 KB,適合L2快取。p50延遲從155 µs降至68 µs,比原始參考快4.8倍。
**最佳化2:點陣圖和內聯打包** 用每節點點陣圖(四個64位字,32位元組)取代check陣列,記錄256個可能位元組中哪些有有效子節點。點陣圖查詢編譯為單個64位字的位測試。同時將所有四個欄位(點陣圖、基址、token ID和分數)打包到單個64位元組快取行中。代價是trie大小從9 MB增至約50 MB,但熱工作集仍約100 KB。p50進一步降低4.5%,L2訪問從4.6K降至1.8K。
**最佳化3:大頁面支援** 50 MB trie在預設4 KB頁面下跨越約12,000個虛擬頁面,導致TLB缺失。Perplexity使用MAP_HUGETLB標誌透過mmap將trie對映到2 MB大頁面,50 MB僅佔25個頁面。根據輸入長度,延遲降低3-12%,最大增益在4,098 token時達12.0%。
最終基準結果
在Intel Xeon Platinum 8488C單執行緒,10,000次迭代,514 token下:
- Hugging Face tokenizers crate:349 µs,3.60M指令,7,295次分配
- SentencePiece(C++):128 µs,1.83M指令,1,559次分配
- IREE分詞器(C):112 µs,2.28M指令,1次分配
- Perplexity最終版本:~63 µs,1.04M指令,0次分配
完整最佳化序列使每次編碼指令數從3.66M降至1.04M,降低3.5倍。在長輸入上效能優勢更大。最終編碼器輸出與參考完全一致,生產中透過rayon實現跨核心並行。
開源釋出
Perplexity AI 已將重寫的Unigram分詞器開源在pplx-garden,三項針對性最佳化去除了熱路徑上的浪費工作。開源社群可立即使用或進一步最佳化。