<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Tokenizer on KbWen Blog</title>
    <link>https://www.kbwen.com/tags/tokenizer/</link>
    <description>KbWen is a practical technology blog about AI systems, machine learning, Python, data engineering, and software development.</description>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <image>
      <url>https://www.kbwen.com/images/og-default.png</url>
      <title>KbWen Blog</title>
      <link>https://www.kbwen.com/</link>
    </image>
    
    <lastBuildDate>Mon, 27 Jul 2026 10:00:00 +0800</lastBuildDate><atom:link href="https://www.kbwen.com/tags/tokenizer/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Tokenization 到底佔多少成本？從 0.1% 到 99% 的落差是怎麼來的</title>
      <link>https://www.kbwen.com/how-much-does-tokenization-cost/</link>
      <pubDate>Mon, 27 Jul 2026 10:00:00 +0800</pubDate><dc:creator>KbWen</dc:creator>
      <guid>https://www.kbwen.com/how-much-does-tokenization-cost/</guid>
      <description>同一串討論底下，有人量到 tokenization 不到總推論時間的 0.1%，也有人量到九成以上的 CPU 時間都花在這裡。這篇看這個落差怎麼來的：算的窗口不同、模型大小不同，還有一些工作根本沒有模型在裡面。</description>
      <content:encoded><![CDATA[<blockquote>
<p><strong>TL;DR：</strong> 0.1%、一成以上、九成以上，這是同一串討論裡三個人各自量到的 tokenization 佔比：一個看的是整段推論，一個做 64M 參數的小模型分類，一個每次搜尋都要當場算 embedding。Gigatoken 作者自己貼的推論端實測是平均 TTFT 改善 5.5% 到 8.4%，而他主要的用途是離線資料處理，那種工作要跑上好幾天。</p>
</blockquote>
<p>tokenization 佔一個系統多少成本，答案的落差很大：有人量到不到總推論時間的 0.1%，也有人量到九成以上的 CPU 時間都花在這裡。這些說法出現在同一串討論底下，講的人各自在做不同的系統。</p>
<p>Tokenizer 是把文字切成 token 的那一套程式，token 本身是什麼可以參考<a href="/what-is-token-in-llm/">Token 是什麼？LLM 為何只讀 Token？</a>。這串<a href="https://news.ycombinator.com/item?id=49010167">討論</a>來自 <a href="https://github.com/marcelroed/gigatoken">Gigatoken</a> 這個 tokenizer 專案，作者 Marcel Rød 本人也在裡面回覆。討論串裡的數字多半是各自報上來的，Gigatoken 那組也還沒有第三方的重測。落差這麼大，是因為 tokenizer 在每個人的系統裡站的位置不一樣。</p>
<h2 id="推論裡佔多少">推論裡佔多少</h2>
<p>有人留言說，tokenization 在整個推論時間裡通常不到 0.1%。作者接的是另一個窗口：TTFT 算的是從輸入送進去到模型吐出第一個 token 為止，中間包含把整段 prompt 讀完的 prefill，而 prefill 這一段每個 token 花掉的 GPU 時間比後面低很多，tokenization 在裡面的比重就跟著高起來。</p>
<p>他後來貼了一組實測：8B 的 Qwen3、單張 B200，輸入長度 2048 的時候，平均 TTFT 從 30.74 ms 降到 29.05 ms，大約 5.5%；8192 是 105.20 ms 降到 96.36 ms，8.4%；32768 是 687.05 ms 降到 633.66 ms，7.8%。他註明這些是初步數字，還要再測。一個看的是整段推論，一個看到第一個 token 為止，量的東西不同，數字自然對不起來。</p>
<h2 id="小模型的情況">小模型的情況</h2>
<p>一位留言的人講了幾年前做過的分類系統：模型是 64M 參數的 BERT，系統其他部分每秒能處理幾 GB 的資料，tokenizer 只有每秒幾 MB，整條線就卡在這裡。他說模型推論比 tokenization 貴，但 tokenization 還是佔掉「&gt;10% of total runtime」。模型只有 64M，本來就吃不掉多少時間，tokenizer 的比重跟著被抬上去。</p>
<h2 id="模型之外的工作">模型之外的工作</h2>
<p>有些工作，模型根本還沒進場。另一個人有一批資料沒辦法把要做語意搜尋的 metadata 存下來，只好每次搜尋都當場把文字轉成 embedding，tokenizing 佔掉九成以上的 CPU 時間。他自己補了原因：預設 tokenizer 的實作很天真，複雜度隨文件長度平方成長，換成一個像樣的 scanner 之後大部分問題就沒了，連 SIMD 都還沒用上。</p>
<p>作者自己的用途也在這一類。他做的是預訓練實驗，資料的混比、過濾、處理方式一改就得重跑一遍，而切分做在 token 這一層，不在文字那一層；這種工作他們是「run for days on a huge number of CPUs」，跑的是 DCLM 那種規模的資料。</p>
<p>再往前一點還有一種，跟百分比沒什麼關係。一個做 AI 平台的人說，他們需要很早就把 token 切出來，後面的分流、流量限制這些判斷都靠它；他也說這在一次請求的端到端時間裡佔比不大，可是還是得做得快。</p>
<h2 id="gigatoken-自己的數字">Gigatoken 自己的數字</h2>
<p>工具這一邊也有同樣的落差。Gigatoken 的 README 開頭寫著「~1000x faster than HuggingFace&rsquo;s tokenizers, drop-in replacement.」，而 benchmark 跑的是 owt_train.txt，一份 11.9 GB 的純文字檔，機器是配 AMD EPYC 9565、合計 144 核。</p>
<table>
  <thead>
      <tr>
          <th>Tokenizer</th>
          <th style="text-align: right">gigatoken</th>
          <th style="text-align: right">HF tokenizers</th>
          <th style="text-align: right">倍率</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>GPT-2</td>
          <td style="text-align: right">24.53 GB/s</td>
          <td style="text-align: right">24.8 MB/s</td>
          <td style="text-align: right">989×</td>
      </tr>
      <tr>
          <td>Qwen 3</td>
          <td style="text-align: right">22.16 GB/s</td>
          <td style="text-align: right">34.2 MB/s</td>
          <td style="text-align: right">648×</td>
      </tr>
      <tr>
          <td>Gemma 1</td>
          <td style="text-align: right">2.51 GB/s</td>
          <td style="text-align: right">342.2 MB/s</td>
          <td style="text-align: right">7.3×</td>
      </tr>
  </tbody>
</table>
<p>機器相同，檔案也沒換，不一樣的只有那一列用的 tokenizer。README 寫著「The slowest rows are the SentencePiece-based tokenizers, which are not well optimized in Gigatoken.」Gemma 系列、Mistral、CodeLlama 這幾列都在同一段範圍裡，倍率全在十幾倍以下。</p>
<p>量測條件本身也決定了數字的大小。gigatoken 讀的是整份沒有切開的檔案，連邊界要落在哪、怎麼自動平行化都得自己處理；HuggingFace tokenizers 拿到的是前 100 MB，tiktoken 拿到前 1 GB，兩邊拿到的內容都事先照 <code>&lt;|endoftext|&gt;</code> 切好了。對照組收到的是一份份完整的文件，不是一個個詞彙。只量前面一段這件事，作者說是公平的，理由是被比的兩套都沒有做快取，速度從頭到尾大致均勻。事先切好這一項，那段沒有另外說明。README 註明，拿來比的兩套本身就是多執行緒的 Rust 程式。</p>
<p>呼叫的方式也差一輪。表上的數字要走 gigatoken 自己的 API 才拿得到。換成相容模式，也就是把現有的 HuggingFace tokenizer 包一層、其他程式都不動的用法，README 說作者在這上面花了不少工夫，讓輸出跟 HuggingFace 對得起來，代價是「a non-negligible cost to performance」，走這條路一樣會快很多，「but not quite the 1000x you will get with the Gigatoken API」。作者給的量級是大概 200 到 300 倍。</p>
<h2 id="延遲跟吞吐量">延遲跟吞吐量</h2>
<p>討論串裡有人算了一個具體的例子：假設 tokenization 花 10 ms、後面的推論步驟花 50 ms，把 tokenization 加快，改善的是到第一個 token 的時間，對吞吐量影響不大；第一個 token 之後，推論本身就把 tokenization 的時間蓋過去了。</p>
<p>這篇是照著 README 跟那串討論整理的，數字多半是當事人自己報的，版本一改可能就對不上；可能有錯，發現的話會盡快修改～</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
