
Sharptoken ist eine C# -Bibliothek, die als Hafen der Python Tiktoken -Bibliothek dient. Es bietet Funktionen für die Codierung und Dekodierung von Token mit GPT-basierten Codierungen. Diese Bibliothek wurde für .NET 6, .NET 8 und .NET Standard 2.0 erstellt, wodurch sie mit einer Vielzahl von Frameworks kompatibel ist.
Wichtig
Die Funktionalität in SharpToken wurde zu Microsoft.ML.Tokenizers hinzugefügt. Microsoft.ML.Tokenizers ist eine Tokenizer -Bibliothek, die vom .NET -Team entwickelt wird und in Zukunft den zentralen Ort für die Entwicklung von Tokenizer in .NET. Durch die Verwendung Microsoft.ML.Tokenizers sollten Sie eine verbesserte Leistung gegenüber den Implementierungen der vorhandenen Tokenizer -Bibliothek, einschließlich SharpToken , feststellen. Eine stabile Veröffentlichung von Microsoft.ML.Tokenizers wird neben der Veröffentlichung von .NET 9.0 (November 2024) erwartet. Anweisungen zur Migration finden Sie unter https://github.com/dotnet/maachinelearning/blob/main/docs/code/microsoft-ml-tekers-migration-guide.md.
Verwenden Sie zum Installieren von Sharptoken den Nuget -Paket -Manager:
Install-Package SharpTokenOder, wenn Sie es vorziehen, die .NET -CLI zu verwenden:
dotnet add package SharpTokenWeitere Informationen finden Sie auf der Nuget -Paket -Seite.
Um Sharptoken in Ihrem Projekt zu verwenden, importieren Sie zunächst die Bibliothek:
using SharpToken ;Erstellen Sie als nächstes eine Instanz des Gptencoding, indem Sie die gewünschte Codierung oder das gewünschte Modell angeben:
// Get encoding by encoding name
var encoding = GptEncoding . GetEncoding ( " cl100k_base " ) ;
// Get encoding by model name
var encoding = GptEncoding . GetEncodingForModel ( " gpt-4 " ) ;Sie können dann die Encodemethode verwenden, um eine Zeichenfolge zu codieren:
var encoded = encoding . Encode ( " Hello, world! " ) ; // Output: [9906, 11, 1917, 0]Und verwenden Sie die Dekodemethode, um die codierten Token zu dekodieren:
var decoded = encoding . Decode ( encoded ) ; // Output: "Hello, world!"Sharptoken bietet auch eine Hochleistungszählmethode. Es ist nützlich, um die Eingabeaufforderung zu überprüfen, bevor Sie sie an einen LLM senden oder in einem Texten/Chunker für RAG verwenden.
var count = encoding . CountTokens ( " Hello, world! " ) ; // Output: 4 Sharptoken unterstützt derzeit die folgenden Modelle:
r50k_basep50k_basep50k_editcl100k_baseo200k_baseSie können eines dieser Modelle verwenden, wenn Sie eine Instanz von gptencoding erstellen:
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 " ) ;Neben der Angabe von direkten Modellnamen bietet Sharptoken auch Funktionen, um Modellnamen basierend auf bestimmten Präfixen zu kartieren. Auf diese Weise können Benutzer eine Codierung basierend auf dem Präfix eines Modells abrufen.
Hier sind die aktuell unterstützten Präfixe und ihre entsprechenden Codierungen:
| Modellpräfix | Codierung |
|---|---|
gpt-4o | o200k_base |
gpt-4- | cl100k_base |
gpt-3.5-turbo- | cl100k_base |
gpt-35-turbo | cl100k_base |
Beispiele für Modellnamen, die unter diese Präfixe fallen, sind:
gpt-4o : gpt-4o , gpt-4o-2024-05-13 usw.gpt-4- : gpt-4-0314 , gpt-4-32k usw.gpt-3.5-turbo- : gpt-3.5-turbo-0301 , gpt-3.5-turbo-0401 usw.gpt-35-turbo . Um den Codierungsnamen basierend auf einem Modellnamen oder seinem Präfix abzurufen, können Sie die GetEncodingNameForModel -Methode verwenden:
string encodingName = Model . GetEncodingNameForModel ( " gpt-4-0314 " ) ; // This will return "cl100k_base" Wenn der angegebene Modellname nicht übereinstimmende Modellnamen oder Präfixe übereinstimmt, gibt die Methode null zurück.
Wenn Sie eine Zeichenfolge unter Verwendung der Encode -Methode codieren, ist der zurückgegebene Wert eine Liste von Ganzzahlen, die Token in der angegebenen Codierung darstellen. Diese Token sind eine kompakte Methode, um den Eingangstext darzustellen und können von verschiedenen Algorithmen effizienter verarbeitet werden.
Zum Beispiel den Text "Hello World!" Die Verwendung der CL100K_BASE -Codierung kann die folgende Liste der Ganzzahlen erstellen:
var encoded = cl100kBaseEncoding . Encode ( " Hello world! " ) ; // Output: [9906, 1917, 0] Sie können dann die Decode verwenden, um diese tokenisierten Ganzzahlwerte in den Originaltext umzuwandeln:
var decoded = cl100kBaseEncoding . Decode ( encoded ) ; // Output: "Hello world!" Mit Sharptoken können Sie nahtlos zwischen verschiedenen Codierungen wechseln, um die zu finden, die Ihren Anforderungen am besten entspricht. Denken Sie nur daran, die gleiche Codierung sowohl für die Encode als auch für die Decode zu verwenden, um genaue Ergebnisse zu gewährleisten.
Mit Sharptoken können Sie benutzerdefinierte Sätze von zulässigen speziellen Token angeben, wenn Sie Text codieren. Geben Sie dazu einen Hashset, der die zulässigen Spezialparks als Parameter an die Encode -Methode enthält, übergeben:
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 ) ; In ähnlicher Weise können Sie benutzerdefinierte Sätze von nicht zugelassenen speziellen Token bei Codierung von Text angeben. Übergeben Sie einen HashSet<string> der die nicht zugelassenen Special -Token als Parameter an die Encode -Methode enthält:
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 ) ; In diesem Beispiel wird ein ArgumentException geworfen
Sharptoken enthält eine Reihe von Testfällen in der Datei testPlans.txt, um seine Kompatibilität mit der Python Tiktoken -Bibliothek sicherzustellen. Diese Testfälle validieren die Funktionalität und das Verhalten von Sharptoken und bieten Entwicklern eine zuverlässige Referenz. Durch das Ausführen der Unit -Tests und die Überprüfung der Testfälle können Sie die Konsistenz zwischen der C# Sharptoken -Bibliothek und der ursprünglichen Python -Implementierung aufrechterhalten.
Sharptoken ist die schnellste Bibliothek mit den niedrigsten Zuweisungen!
[ 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
| Verfahren | Arbeit | Laufzeit | Bedeuten | Fehler | Stddev | Mittlere | Gen0 | Gen1 | Zugewiesen |
|---|---|---|---|---|---|---|---|---|---|
| MlTokenizers | .NET 8.0 | .NET 8.0 | 60,55 ms | 1,143 ms | 1,123 ms | 60,45 ms | 1000.0000 | - - | 13.12 MB |
| MlTokenizers | .NET 6.0 | .NET 6.0 | 95,75 ms | 1,374 ms | 1,147 ms | 95,54 ms | 10500.0000 | - - | 126,19 MB |
| MlTokenizers | .NET Framework 4.7.1 | .NET Framework 4.7.1 | 291,77 ms | 5.811 ms | 11.195 ms | 291,64 ms | 21000.0000 | - - | 127,33 MB |
| Sharptoken | .NET 8.0 | .NET 8.0 | 87,78 ms | 1,700 ms | 1,590 ms | 87,34 ms | 1000.0000 | - - | 22.13 MB |
| Sharptoken | .NET 6.0 | .NET 6.0 | 128,84 ms | 1,718 ms | 1,607 ms | 128,17 ms | 16250.0000 | 500.0000 | 196.31 MB |
| Sharptoken | .NET Framework 4.7.1 | .NET Framework 4.7.1 | 356,21 ms | 6,843 ms | 10,854 ms | 355.09 ms | 34000.0000 | 1000.0000 | 204,39 MB |
| Tokenizerlib | .NET 8.0 | .NET 8.0 | 109,26 ms | 2,082 ms | 4,482 ms | 107,90 ms | 18200.0000 | 600.0000 | 217,82 MB |
| Tokenizerlib | .NET 6.0 | .NET 6.0 | 126,16 ms | 2,959 ms | 8,630 ms | 122,34 ms | 18000.0000 | 500.0000 | 217,82 MB |
| Tokenizerlib | .NET Framework 4.7.1 | .NET Framework 4.7.1 | 374.71 ms | 7,374 ms | 16.794 ms | 370,12 ms | 40000.0000 | 1000.0000 | 243,79 MB |
| Tiktokensharp | .NET 8.0 | .NET 8.0 | 177.34 ms | 3,506 ms | 8,797 ms | 174,98 ms | 28000.0000 | 1000.0000 | 338,98 MB |
| Tiktokensharp | .NET 6.0 | .NET 6.0 | 196.17 ms | 3,912 ms | 8,422 ms | 195,52 ms | 26000.0000 | 666.6667 | 313.26 MB |
| Tiktokensharp | .NET Framework 4.7.1 | .NET Framework 4.7.1 | 488,22 ms | 9.696 ms | 15.931 ms | 487,17 ms | 63000.0000 | 1000.0000 | 378,31 MB |
Sharptoken ist auf Net8.0 extrem leistungsoptimiert. Es verwendet moderne Multibyte -CPU -Anweisungen und fast keine Haufen zuzuweisen.
Alle Kernmethoden wurden auf einem großen und kleinen Eingabetxt getestet.
Eingänge:
SmallText : 453 B (Text/Ebene)LargeText : 51 kb (text/html)Methoden:
Encode : text an tokensDecode : Token zum TextCountTokens : Hochleistungs -API zum Zählen von Text -Token von Text 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
| Verfahren | Bedeuten | Fehler | Stddev | Verhältnis | Verhältnisse | Zugewiesen | Alloc -Verhältnis |
|---|---|---|---|---|---|---|---|
| .NET 8.0 | |||||||
| COD_SmallText | 22.649 US | 0,4244 US | 0,4359 US | 0,28 | 0,01 | 696 b | 0,02 |
| COD_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 | |||||||
| COD_SmallText | 36.370 US | 0,7178 US | 1.0962 US | 0,45 | 0,02 | 37344 b | 0,91 |
| COD_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 Framework 4.7.1 | |||||||
| COD_SmallText | 79,947 US | 1.5621 US | 3.0097 US | 1.00 | 0,00 | 41138 b | 1.00 |
| COD_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 |
Wenn Sie auf Probleme stoßen oder Vorschläge für Verbesserungen haben, können Sie bitte ein Problem eröffnen oder eine Pull -Anfrage im Repository des Projekts einreichen.
Ich hoffe, Sie finden Sharptoken für Ihre Projekte nützlich und begrüßen alle Feedback, die Sie möglicherweise haben.