
Sharptokenは、Python Tiktokenライブラリのポートとして機能するC#ライブラリです。 GPTベースのエンコーディングを使用して、トークンをエンコードおよびデコードする機能を提供します。このライブラリは、.NET 6、.NET 8、および.NET標準2.0用に構築されており、幅広いフレームワークと互換性があります。
重要
SharpTokenの機能はMicrosoft.ML.Tokenizersに追加されました。 Microsoft.ML.Tokenizers 、.NETチームによって開発されているトークネイザーライブラリであり、今後は.NETのトークン剤開発のための中心的な場所です。 Microsoft.ML.Tokenizersを使用することにより、 SharpTokenを含む既存のトークナイザーライブラリの実装よりもパフォーマンスが向上することがわかります。 Microsoft.ML.Tokenizersの安定したリリースは、.NET 9.0リリース(2024年11月)とともに予想されます。移行の指示は、https://github.com/dotnet/machinelearning/blob/main/docs/code/microsoft-ml-tokenizers-migration-guide.mdにあります。
Sharptokenをインストールするには、Nugetパッケージマネージャーを使用してください。
Install-Package SharpTokenまたは、.NET CLIを使用することを好む場合:
dotnet add package SharpToken詳細については、Nugetパッケージページをご覧ください。
プロジェクトでSharptokenを使用するには、最初にライブラリをインポートします。
using SharpToken ;次に、目的のエンコードまたはモデルを指定して、gptencodingのインスタンスを作成します。
// Get encoding by encoding name
var encoding = GptEncoding . GetEncoding ( " cl100k_base " ) ;
// Get encoding by model name
var encoding = GptEncoding . GetEncodingForModel ( " gpt-4 " ) ;その後、エンコードメソッドを使用して、文字列をエンコードできます。
var encoded = encoding . Encode ( " Hello, world! " ) ; // Output: [9906, 11, 1917, 0]デコードメソッドを使用して、エンコードされたトークンをデコードします。
var decoded = encoding . Decode ( encoded ) ; // Output: "Hello, world!"Sharptokenは、高性能カウント方法も提供します。 LLMに送信する前に、プロンプトサイズをチェックするか、ぼろきれのテキストスプリッター/チャンカーで使用すると便利です。
var count = encoding . CountTokens ( " Hello, world! " ) ; // Output: 4 Sharptokenは現在、次のモデルをサポートしています。
r50k_basep50k_basep50k_editcl100k_baseo200k_baseこれらのモデルのいずれかを使用すると、gptencodingのインスタンスを作成できます。
var r50kBaseEncoding = GptEncoding . GetEncoding ( " r50k_base " ) ;
var p50kBaseEncoding = GptEncoding . GetEncoding ( " p50k_base " ) ;
var p50kEditEncoding = GptEncoding . GetEncoding ( " p50k_edit " ) ;
var cl100kBaseEncoding = GptEncoding . GetEncoding ( " cl100k_base " ) ;
var o200kBaseEncoding = GptEncoding . GetEncoding ( " o200k_base " ) ;直接モデル名の指定とは別に、Sharptokenは特定のプレフィックスに基づいてモデル名をマップする機能も提供します。これにより、ユーザーはモデルのプレフィックスに基づいてエンコードを取得できます。
現在サポートされているプレフィックスとそれらの対応するエンコーディングは次のとおりです。
| モデルプレフィックス | エンコーディング |
|---|---|
gpt-4o | o200k_base |
gpt-4- | cl100k_base |
gpt-3.5-turbo- | cl100k_base |
gpt-35-turbo | cl100k_base |
これらのプレフィックスに該当するモデル名の例は次のとおりです。
gpt-4o : gpt-4o 、 gpt-4o-2024-05-13など。gpt-4- : gpt-4-0314 、 gpt-4-32kなど。gpt-3.5-turbo- : gpt-3.5-turbo-0301 、 gpt-3.5-turbo-0401など。gpt-35-turboの場合。モデル名またはそのプレフィックスに基づいてエンコード名を取得するには、 GetEncodingNameForModelメソッドを使用できます。
string encodingName = Model . GetEncodingNameForModel ( " gpt-4-0314 " ) ; // This will return "cl100k_base"提供されたモデル名が直接モデル名またはプレフィックスと一致しない場合、メソッドはnullを返します。
エンコードメソッドを使用して文字列をエンコードする場合、返された値は、指定されたエンコードのトークンを表す整数のリストです。これらのトークンは、入力テキストを表すコンパクトな方法であり、さまざまなアルゴリズムによってより効率的に処理できます。
たとえば、「Hello World!」というテキストをエンコードするCL100K_BASEエンコードを使用すると、次の整数リストが生成される場合があります。
var encoded = cl100kBaseEncoding . Encode ( " Hello world! " ) ; // Output: [9906, 1917, 0]その後、 Decode法を使用して、これらのトークン化された整数値を元のテキストに変換できます。
var decoded = cl100kBaseEncoding . Decode ( encoded ) ; // Output: "Hello world!" Sharptokenを使用すると、さまざまなエンコードをシームレスに切り替えて、ニーズに最適なエンコーディングを見つけることができます。正確な結果を確実にするために、 EncodeとDecodeメソッドの両方に同じエンコードを使用することを忘れないでください。
Sharptokenを使用すると、テキストをエンコードするときに許可された特別なトークンのカスタムセットを指定できます。これを行うには、エンコードメソッドのパラメーターとして許可された特別なトークンを含むハッシュセットを渡します。
const string encodingName = " cl100k_base " ;
const string inputText = " Some Text <|endofprompt|> " ;
var allowedSpecialTokens = new HashSet < string > { " <|endofprompt|> " } ;
var encoding = GptEncoding . GetEncoding ( encodingName ) ;
var encoded = encoding . Encode ( inputText , allowedSpecialTokens ) ;
var expectedEncoded = new List < int > { 8538 , 2991 , 220 , 100276 } ;
Assert . Equal ( expectedEncoded , encoded ) ;同様に、テキストをエンコードするときに、許可されていない特別なトークンのカスタムセットを指定できます。エンコードメソッドのパラメーターとして許可されていない特別なトークンを含むHashSet<string>を渡します。
const string encodingName = " cl100k_base " ;
const string inputText = " Some Text " ;
var encoding = GptEncoding . GetEncoding ( encodingName ) ;
void TestAction ( )
{
encoding . Encode ( inputText , disallowedSpecial : new HashSet < string > { " Some " } ) ;
}
Assert . Throws < ArgumentException > ( TestAction ) ;この例では、入力テキストには許可されていない特別なトークンが含まれているため、 ArgumentExceptionがスローされます
Sharptokenには、Python Tiktokenライブラリとの互換性を確保するためのTestPlans.txtファイルにテストケースのセットが含まれています。これらのテストケースは、Sharptokenの機能と動作を検証し、開発者に信頼できるリファレンスを提供します。ユニットテストを実行し、テストケースを検証するのは、C#Sharptokenライブラリと元のPython実装との間の一貫性を維持するのに役立ちます。
Sharptokenは、最も低い割り当てを持つ最速のライブラリです!
[ SimpleJob ( RuntimeMoniker . Net60 ) ]
[ SimpleJob ( RuntimeMoniker . Net80 ) ]
[ SimpleJob ( RuntimeMoniker . Net471 ) ]
[ RPlotExporter ]
[ MemoryDiagnoser ]
public class CompareBenchmark
{
private GptEncoding _sharpToken ;
private TikToken _tikToken ;
private ITokenizer _tokenizer ;
private Tokenizer _mlTokenizer ;
private string _kLongText ;
[ GlobalSetup ]
public async Task Setup ( )
{
_sharpToken = GptEncoding . GetEncoding ( " cl100k_base " ) ;
_tikToken = await TikToken . GetEncodingAsync ( " cl100k_base " ) . ConfigureAwait ( false ) ;
_tokenizer = await TokenizerBuilder . CreateByModelNameAsync ( " gpt-4 " ) . ConfigureAwait ( false ) ;
_kLongText = " King Lear, one of Shakespeare's darkest and most savage plays, tells the story of the foolish and Job-like Lear, who divides his kingdom, as he does his affections, according to vanity and whim. Lear’s failure as a father engulfs himself and his world in turmoil and tragedy. " ;
}
[ Benchmark ]
public int SharpToken ( )
{
var sum = 0 ;
for ( var i = 0 ; i < 10000 ; i ++ )
{
var encoded = _sharpToken . Encode ( _kLongText ) ;
var decoded = _sharpToken . Decode ( encoded ) ;
sum += decoded . Length ;
}
return sum ;
}
[ Benchmark ]
public int TiktokenSharp ( )
{
var sum = 0 ;
for ( var i = 0 ; i < 10000 ; i ++ )
{
var encoded = _tikToken . Encode ( _kLongText ) ;
var decoded = _tikToken . Decode ( encoded ) ;
sum += decoded . Length ;
}
return sum ;
}
[ Benchmark ]
public int TokenizerLib ( )
{
var sum = 0 ;
for ( var i = 0 ; i < 10000 ; i ++ )
{
var encoded = _tokenizer . Encode ( _kLongText ) ;
var decoded = _tokenizer . Decode ( encoded . ToArray ( ) ) ;
sum += decoded . Length ;
}
return sum ;
}
[ Benchmark ]
public int MLTokenizers ( )
{
var sum = 0 ;
for ( var i = 0 ; i < 10000 ; i ++ )
{
var encoded = _mlTokenizer . EncodeToIds ( _kLongText ) ;
var decoded = _mlTokenizer . Decode ( encoded ) ;
sum += decoded . Length ;
}
return sum ;
}
} BenchmarkDotNet v0.13.9+228a464e8be6c580ad9408e98f18813f6407fb5a, Windows 11 (10.0.22631.3296)
11th Gen Intel Core i9-11950H 2.60GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK 9.0.100-preview.2.24157.14
[Host] : .NET 8.0.3 (8.0.324.11423), X64 RyuJIT AVX2
.NET 6.0 : .NET 6.0.28 (6.0.2824.12007), X64 RyuJIT AVX2
.NET 8.0 : .NET 8.0.3 (8.0.324.11423), X64 RyuJIT AVX2
.NET Framework 4.7.1 : .NET Framework 4.8.1 (4.8.9181.0), X64 RyuJIT VectorSize=256
| 方法 | 仕事 | ランタイム | 平均 | エラー | stddev | 中央値 | GEN0 | Gen1 | 割り当てられます |
|---|---|---|---|---|---|---|---|---|---|
| mltokenizers | .NET 8.0 | .NET 8.0 | 60.55ミリ秒 | 1.143ミリ秒 | 1.123ミリ秒 | 60.45ミリ秒 | 1000.0000 | - | 13.12 MB |
| mltokenizers | .NET 6.0 | .NET 6.0 | 95.75ミリ秒 | 1.374ミリ秒 | 1.147ミリ秒 | 95.54ミリ秒 | 10500.0000 | - | 126.19 MB |
| mltokenizers | .NETフレームワーク4.7.1 | .NETフレームワーク4.7.1 | 291.77ミリ秒 | 5.811 ms | 11.195ミリ秒 | 291.64 ms | 21000.0000 | - | 127.33 MB |
| シャルプトン | .NET 8.0 | .NET 8.0 | 87.78 ms | 1.700ミリ秒 | 1.590ミリ秒 | 87.34 ms | 1000.0000 | - | 22.13 MB |
| シャルプトン | .NET 6.0 | .NET 6.0 | 128.84 ms | 1.718ミリ秒 | 1.607ミリ秒 | 128.17ミリ秒 | 16250.0000 | 500.0000 | 196.31 MB |
| シャルプトン | .NETフレームワーク4.7.1 | .NETフレームワーク4.7.1 | 356.21 ms | 6.843ミリ秒 | 10.854 ms | 355.09 ms | 34000.0000 | 1000.0000 | 204.39 MB |
| Tokenizerlib | .NET 8.0 | .NET 8.0 | 109.26ミリ秒 | 2.082ミリ秒 | 4.482ミリ秒 | 107.90ミリ秒 | 18200.0000 | 600.0000 | 217.82 MB |
| Tokenizerlib | .NET 6.0 | .NET 6.0 | 126.16ミリ秒 | 2.959ミリ秒 | 8.630ミリ秒 | 122.34 ms | 18000.0000 | 500.0000 | 217.82 MB |
| Tokenizerlib | .NETフレームワーク4.7.1 | .NETフレームワーク4.7.1 | 374.71 ms | 7.374 ms | 16.794ミリ秒 | 370.12 ms | 40000.0000 | 1000.0000 | 243.79 MB |
| Tiktokensharp | .NET 8.0 | .NET 8.0 | 177.34 ms | 3.506ミリ秒 | 8.797ミリ秒 | 174.98 ms | 28000.0000 | 1000.0000 | 338.98 MB |
| Tiktokensharp | .NET 6.0 | .NET 6.0 | 196.17ミリ秒 | 3.912 ms | 8.422ミリ秒 | 195.52ミリ秒 | 26000.0000 | 666.6667 | 313.26 MB |
| Tiktokensharp | .NETフレームワーク4.7.1 | .NETフレームワーク4.7.1 | 488.22 ms | 9.696ミリ秒 | 15.931 ms | 487.17 ms | 63000.0000 | 1000.0000 | 378.31 MB |
Sharptokenは、Net8.0で最適化されているため、めちゃくちゃパフォーマンスです。最新のマルチバイトCPU命令を使用しており、ヒープの割り当てはほとんどありません。
すべてのコアメソッドは、大規模および小さな入力テキストでテストされています。
入力:
SmallText :453 B(テキスト/プレーン)LargeText :51 kb(テキスト/html)方法:
Encode :テキストからトークンDecode :テキストへのトークンCountTokens :テキストのトークンをカウントする高性能API BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.3296/23H2/2023Update/SunValley3)
AMD Ryzen 9 3900X, 1 CPU, 24 logical and 12 physical cores
.NET SDK 8.0.200
[Host] : .NET 8.0.2 (8.0.224.6711), X64 RyuJIT AVX2
.NET 6.0 : .NET 6.0.16 (6.0.1623.17311), X64 RyuJIT AVX2
.NET 8.0 : .NET 8.0.2 (8.0.224.6711), X64 RyuJIT AVX2
.NET Framework 4.7.1 : .NET Framework 4.8.1 (4.8.9181.0), X64 RyuJIT VectorSize=256
| 方法 | 平均 | エラー | stddev | 比率 | 比率 | 割り当てられます | アロック比 |
|---|---|---|---|---|---|---|---|
| .NET 8.0 | |||||||
| encode_smalltext | 22.649 US | 0.4244 US | 0.4359 US | 0.28 | 0.01 | 696 b | 0.02 |
| encode_largetext | 4,542.505 US | 87.7988 US | 104.5182 US | 0.24 | 0.01 | 155547 b | 0.03 |
| decode_smalltext | 1.623 US | 0.0324 US | 0.0373 US | 0.44 | 0.02 | 2320 b | 0.98 |
| decode_largetext | 454.570 US | 6.8980 US | 6.4524 US | 0.80 | 0.02 | 286979 b | 1.00 |
| counttokens_smalltext | 22.008 US | 0.1165 US | 0.0909 US | 0.28 | 0.00 | 184 b | 0.005 |
| countTokens_largetext | 4,231.353 US | 14.5157 US | 11.3329 US | 0.23 | 0.00 | 195 b | 0.000 |
| .NET 6.0 | |||||||
| encode_smalltext | 36.370 US | 0.7178 US | 1.0962 US | 0.45 | 0.02 | 37344 b | 0.91 |
| encode_largetext | 11,213.070 US | 219.6291 US | 269.7243 US | 0.59 | 0.02 | 5062574 b | 0.91 |
| decode_smalltext | 2.588 US | 0.0394 US | 0.0350 US | 0.70 | 0.02 | 2320 b | 0.98 |
| decode_largetext | 489.467 US | 8.9195 US | 8.3433 US | 0.86 | 0.02 | 286985 b | 1.00 |
| counttokens_smalltext | 34.758 US | 0.2027 US | 0.1896 US | 0.45 | 0.01 | 36832 b | 0.907 |
| countTokens_largetext | 11,252.083 US | 215.8912 US | 212.0340 US | 0.61 | 0.01 | 4907169 b | 0.907 |
| .NETフレームワーク4.7.1 | |||||||
| encode_smalltext | 79.947 US | 1.5621 US | 3.0097 US | 1.00 | 0.00 | 41138 b | 1.00 |
| encode_largetext | 18,961.252 US | 253.1816 US | 236.8262 US | 1.00 | 0.00 | 5567685 b | 1.00 |
| decode_smalltext | 3.723 US | 0.0728 US | 0.0997 US | 1.00 | 0.00 | 2375 b | 1.00 |
| decode_largetext | 570.787 US | 11.0356 US | 11.8080 US | 1.00 | 0.00 | 287496 b | 1.00 |
| counttokens_smalltext | 77.521 US | 1.0802 US | 0.9020 US | 1.00 | 0.00 | 40616 b | 1.000 |
| countTokens_largetext | 18,485.392 US | 313.5834 US | 277.9836 US | 1.00 | 0.00 | 5413237 b | 1.000 |
問題が発生したり、改善の提案がある場合は、問題を公開するか、プロジェクトのリポジトリにプルリクエストを送信してください。
あなたがあなたのプロジェクトに役立つSharptokenを見つけて、あなたが持っているかもしれないフィードバックを歓迎することを願っています。