🐡

C# で Azure OpenAI Service のトークン数を数えよう

2023/04/16に公開

追記

最新の情報はこちらになります。

https://zenn.dev/microsoft/articles/count-token-with-csharp

本文

最近、Azure OpenAI Service の申請通ったので色々遊んでるのですがジャンル的に当然なのですが python のコードで溢れているので C# での例をこれからボチボチ書いていこうと思います。手始めに、トークンのカウントの仕方を書こうと思います。

トークン

トークンは課金単位になっていたり、API を叩く際に、こちらから渡したプロンプトのトークン数とレスポンスのトークン数が所定の値を超えると長すぎというエラーが起きたりするので、トークン数は結構大事です。将来的には gpt-4-32k というモデルで 32,768 トークンがサポートされるようですが現状ではモデルにもよりますが 2,049 トークンや 4,096 トークンだったりするのでトークン数を数えることは結構大事です。

https://learn.microsoft.com/ja-jp/azure/cognitive-services/openai/concepts/models

このトークンの数え方ですが python だと tiktoken というライブラリなどがあり、それを使って数えることができます。

https://github.com/openai/tiktoken

C# 版で似たようなライブラリがないか探してみたところ Tokenizer というライブラリがあったので使ってみました。

https://github.com/microsoft/Tokenizer

使ってみよう

では試してみましょう。コンソールアプリを作って NuGet から Microsoft.DeepDev.TokenizerLib をインストールします。
個人的に、今 gpt-3.5-turbo のモデルを使っているので、それでトークンを数えてみたいと思います。トークンを数えるには TokenizerBuilder.CreateByModelName("gpt-3.5-turbo")tokenizer を作成して Encode メソッドでトークンのリストにします。このリストの長さがトークン数になります。

以下のようなコードを書いて実験してみました。コンソールアプリを作成して Microsoft.DeepDev.TokenizerLibAzure.AI.OpenAI (プレビューパッケージなのでインストール時にはプレビューパッケージも対象にして検索してください) パッケージを追加しています。

using Azure;
using Azure.AI.OpenAI;
using Microsoft.DeepDev;
using Microsoft.Extensions.Configuration;

var c = new ConfigurationBuilder()
    .AddUserSecrets<Program>()
    .Build();
var tokenizer = TokenizerBuilder.CreateByModelName("gpt-3.5-turbo");

Console.WriteLine("トークンを数えたい文字列を入力してください。");
var input = Console.ReadLine()!.Trim();
var encoded = tokenizer.Encode(input, Array.Empty<string>());
Console.WriteLine($"{encoded.Count} tokens.");

var client = new OpenAIClient(
    c.GetValue<Uri>("Endpoint"),
    new AzureKeyCredential(c.GetValue<string>("Key")!));
var result = await client.GetCompletionsAsync(c.GetValue<string>("ModelName"), new CompletionsOptions
{
    MaxTokens = 100,
    Prompts =
    {
        input,
    }
});

Console.WriteLine($"{result.Value.Usage.PromptTokens} tokens.");

手元でトークンを算出したものと、実際に Azure OpenAI Service に問い合わせて戻り値の result.Value.Usage.PromptTokens と比較してみました。

何回か実行して試してみました。

トークンを数えたい文字列を入力してください。
春は曙やうやう白くなりゆく山際少し明かりて紫立ちたる雲の細くたなびきたる。
46 tokens.
46 tokens.
トークンを数えたい文字列を入力してください。
祇園精舍の鐘の声、諸行無常の響きあり。娑羅双樹の花の色、盛者必衰の理をあらはす。驕れる人も久しからず、ただ春の夜の夢のごとし。猛き者もつひにはほろびぬ、ひとへに風の前の塵に同じ。
121 tokens.
121 tokens.

ばっちりですね。これでトークン数を数えることができます。

トークンが数えられると動的にプロンプトを組み立てるときにトークン数を超えないようにすることができます。また、トークン数を超えるとエラーになるので、トークン数を超えるときは API を呼ぶ前にエラーを出すようにすることもできます。便利ですね。

まとめ

これからも、ちょいちょい Azure OpenAI Service 触ってメモ書いていこうと思います~。

Microsoft (有志)

Discussion