💱

LLMプロンプト内の空白・改行に対するトークン数と処理時間の計測

に公開

サマリ

LLMを使用したアプリケーションを開発している際に、空白文字や改行はどの程度料金や処理時間に影響を与えるのかが気になりました。
今回はGeminiを使用して、プロンプトを使用する際に入力された空白文字や改行を付与した際に使用されるトークン数、料金と処理時間にどのような影響があるかを観測しました。

実験

Githubのこのリポジトリを使用します。
https://github.com/KazukiKandaKK/llm-token-check

入力

case inputとして渡される文字列 実際の形(イメージ) 備考
single_space "hello"をWORD_COUNT回並べ、区切りを半角スペース1個 " " にする hello hello hello ... hello 単語+空白区切り
double_space "hello"をWORD_COUNT回並べ、区切りを半角スペース2個 " " にする hello hello hello ... 単語+空白区切り(空白2つ)
quad_space "hello"をWORD_COUNT 回並べ、区切りを半角スペース4個 " "` にする hello hello hello ... Pythonなどのインデントと同様の空白数を入れたケース
tab "hello"をWORD_COUNT回並べ、区切りをタブ"\t"にする hello\thello\thello ... スペース複数個とタブの違いを比較する
newline "hello"をWORD_COUNT回並べ、区切りを改行"\n"にする hello\nhello\nhello\n... 改行についても確認する
newline+4space "hello"をWORD_COUNT回並べ、区切りを"\n "(改行+半角スペース4個)にする hello\n hello\n hello ... yamlやjsonファイルなどのインデント付きを観測する
space+newline "hello"をWORD_COUNT回並べ、区切りを" \n"(半角スペース+改行)にする hello \nhello \nhello \n... 行末スペースが混ざるケース
json_minified payload={"items":[{"id":i,"text":"hello world","meta":{"a":1,"b":2}} for i in range(2000)]} を 空白や改行を入れずに詰めた形式(最小化)で文字列化する(separators=(",", ":")) {"items":[{"id":0,"text":"hello world","meta":{"a":1,"b":2}},{"id":1,...}]} 余計な空白・改行を入れないコンパクトなJSON
json_pretty 上と同じpayloadを改行とインデントを付けた整形済み形式で文字列化する(indent=2) {\n "items": [\n {\n "id": 0,\n ...\n },\n ...\n ]\n} 人間が読みやすいように改行+インデントを増やした“整形JSON”
baseline(hi) 文字列"hi"を入力してcount_tokensを複数回実行 hi API使用の固定費の推定のための極小入力(表のcase列には出ていないが計算に使っている)
warmup 文字列"warmup"を1回だけcount_tokensに流す warmup 初回の実行でコールドスタンバイなどの状況を除去する(結果出力には含めない)

評価項目

項目名 何をしているか 備考
case 実験ケース(入力テキストの整形パターン)の識別名 空白・改行・インデント・JSON整形などの項目名
chars 入力テキストの文字数を計測 入力サイズの指標。改行やインデント増で増える。
tokens Vertex AI(Gemini)の count_tokens による入力テキストのトークン数を取得 料金・コンテキスト枠に直結する指標
lat_ms_mean count_tokens API呼び出しの往復時間(レイテンシ)の平均を算出 ネットワーク等の状況も加味される。
lat_ms_median count_tokens API呼び出しの往復時間(レイテンシ)の中央値を算出 ネットワーク等の状況も加味される。
lat_ms_p95 count_tokens API呼び出しの往復時間(レイテンシ)の95パーセンタイルを算出 ネットワーク等の状況も加味される。
lat_ms_minus_baseline_median 極小入力(例:hi)の中央値レイテンシをベースラインとして差し引いた値を算出 入力依存の可変費を見やすくする

Dockerビルド

docker build -t token-bench:latest .

Google Cloudにログインをする

gcloud auth application-default login

スクリプトを実行

docker run --rm \
  -e GOOGLE_CLOUD_PROJECT=YOUR_PROJECT \
  -e GOOGLE_CLOUD_LOCATION=asia-northeast1 \
  -e GOOGLE_GENAI_USE_VERTEXAI=True \
  -e MODEL=gemini-2.5-flash \
  -e TRIALS=30 \
  -e WORD_COUNT=20000 \
  -v $HOME/.config/gcloud:/root/.config/gcloud:ro \
  -v $PWD/out:/app/out \
  token-bench:latest

実験結果

Wrote:
- out/results.csv
- out/latency.png
- out/tokens.png

          case  chars  tokens  lat_ms_mean  lat_ms_median  lat_ms_p95  lat_ms_minus_baseline_median
   json_pretty 228909   98902    50.203506      50.300292   55.007404                     21.463979
newline+4space 199995   59998    48.946721      49.690042   58.373073                     20.853728
    quad_space 179996   39999    44.386839      44.407417   49.700023                     15.571104
  double_space 139998   39999    44.164574      44.170709   48.372340                     15.334395
  single_space 119999   20000    42.706363      42.973958   49.847696                     14.137645
       newline 119999   39999    42.878575      42.913792   50.049885                     14.077479
 space+newline 139998   59998    42.587978      42.192874   47.007067                     13.356561
           tab 119999   39999    41.388613      41.912480   46.499281                     13.076166
 json_minified 106901   44893    40.687479      41.022771   44.711741                     12.186458

トークン数比較

処理時間比較


トークン数について言えること

  • 空白・改行・インデント・整形は、入力トークン数に影響がある。
  • 同じ単語列でも区切り方でトークン数が増加する。
    • single_space は 20,000 tokens
    • newline / tab / double_space / quad_space は 39,999 tokens(約2倍)
    • Pretty JSON は特に高い
    • json_pretty 98,902 tokens
    • json_minified 44,893 tokens

処理時間について言えること

  • count_tokensの処理時間(レイテンシ)は、tokensに単純比例していない。
  • 今回の結果だと、tokensよりchars(入力サイズ)などの影響が強い。

tokensが倍でも速さが変わらない

  • single_space: chars 119,999 / tokens 20,000 / median 42.974ms
  • newline: chars 119,999 / tokens 39,999 / median 42.914ms
    → charsが同じ状況でtokensが倍でもmedianがほぼ同じ。

tokensが同じでもcharsが増えると遅い

  • space+newline: tokens 59,998 / chars 139,998 / median 42.193ms
  • newline+4space: tokens 59,998 / chars 199,995 / median 49.690ms
    → tokens同じでchars増 → +7.5ms

まとめ

空白文字や改行、タブなどでもトークンは使用されるため少しの空白でも長期的に見るとAPI使用の料金に関わってくることがわかりました。
また、空白文字などは処理時間に大きく影響しないことがわかりました。

Discussion