OpenAI / Azure OpenAI でとりあえずトークン数を数えることってちょいちょいありますよね。今回は C#, TypeScript のついでに Python もメモしておこうかなという話です。
はじめに: トークンとは
トークンとはなんじゃって改めて感じた場合は、 以下の OpenAI のドキュメントを読むと参考になります (なるかな...)。
と雑にふれたところで、さっそく各言語での実装を見ていきます。
Python: tiktoken
これは言うまでもなくtiktoken ですね。サンプルはこんな感じ。
import tiktoken def count_token(text: str, model_name: str) -> int: encoding = tiktoken.encoding_for_model(model_name) token_count = len(encoding.encode(text)) return token_count count = count_token("こんにちは、猫さん", "gpt-3.5-turbo") print(f"{count=}")
model 名から encoding
のオブジェクトを作ることが多いですが、参考までに encoding 名からもできます。各 model の encoding 名はこんな感じ。
Encoding name | OpenAI models |
---|---|
cl100k_base | gpt-4, gpt-3.5-turbo, text-embedding-ada-002 |
p50k_base | Codex models, text-davinci-002, text-davinci-003 |
r50k_base (or gpt2) | GPT-3 models (davinci とか) |
で、コード。
import tiktoken def count_token_from_encoding_name(text: str, encoding_name: str) -> int: encoding = tiktoken.get_encoding(encoding_name) token_count = len(encoding.encode(text)) return token_count count = count_token_from_encoding_name("こんにちわ、猫さん", "cl100k_base") print(f"{count=}")
余談ですが「こんにちは」じゃなくて間違った日本語である「こんにちわ」にするとトークンが増えますね。
C#
Tokenizer
Microsoft が OSS として公開している Tokenizer でトークン数を数えれます。tiktoken の実装をベースにしてるみたいですね。
NuGet で Microsoft.DeepDev.TokenizerLib をインストールしてあとはこんな感じ。実際にトークン数えてるのは26-32行目のメソッド。
`
補足をいくつか書いておきます。
- 28行目の
tokenizer
をインスタンス化するTokenizerBuilder.CreateByModelNameAsync
はちょっとコストがかかるのでモデルが決まりきっててトークン数を数える回数も多いなら singleton で保持しておいた方がよさそう。 - 31行目は、トークンを数えるテキストに対して29行目でトークンを追加しているので、その分で2を引いています。
TokenizerBuilder.CreateByEncoderNameAsync
メソッドを使って encoder name で tokenizer の初期化もできます。- model name や encoder name は実装から一覧をみて書いた方がよさそう。
- Tokenizer/Tokenizer_C#/TokenizerLib/TokenizerBuilder.cs
- これ書いてる時点だと、model 名が OpenAI の方の名称をベースにしている。そのため Azure AI Studio で表示される model name:
gpt-35-turbo
だとエラー、OpenAI での model name:gpt-3.5-turbo
としないとあかんとか微妙な点があるため。
Semantic Kernel: GPT3Tokenizer
Semantic Kernel の中に GPT3Tokenizer ってのがあってこんな感じでサクッと使えます。
using Microsoft.SemanticKernel.Connectors.AI.OpenAI.Tokenizers; const string sampleText = ""; var tokenCount = GPT3Tokenizer.Encode(sampleText);
実装を見るとまだこのひとつしかないみたい。これは p50k_base
のエンコーダーで、で足りているので、text-davinci-003 や code-davinci-002 で使われているやつ。つまり、gpt-4, gpt-3.5-turbo や text-embedding-ada-002 で使われている cl100k_base
とは異なる古いやつなので、積極的に使えるものでなない。ということで、Tokenizer 使いましょうって話になります。
TypeScript (JavaScript)
Tokenizer
TypeScript は、先述の C# と同じ repo で Microsoft が OSS として公開している Tokenizer でやれます。
GitHub Packages Registry を使ってるのでそこから package をダウンロードしつつ C# と似た実装で処理するって感じです。C# とあまり変わらないので参考リンクだけにしておきます (C# と Python は私が使ってるで書いたけど、TS は今のとこ使う予定無いのでメモだけでいいやと雑に扱いました)。
GPT-3-Encoder
GPT-3-Encoder もあるけど、最近更新されてないから Tokenizer 使った方が無難です。