
Sharptoken - это библиотека C#, которая служит портом библиотеки Python Tiktoken. Он обеспечивает функциональность для кодирования и декодирования токенов с использованием кодировки на основе GPT. Эта библиотека построена для .NET 6, .NET 8 и .NET STANDANTION 2.0, что делает ее совместимым с широким диапазоном каркасов.
Важный
Функциональность в SharpToken была добавлена в Microsoft.ML.Tokenizers . Microsoft.ML.Tokenizers - это библиотека токенизаторов, разработанную командой .NET и в будущем, центральное место для разработки токенизатора в .NET. Используя Microsoft.ML.Tokenizers , вы должны увидеть улучшенную производительность по сравнению с существующими реализациями библиотеки токенизаторов, включая SharpToken . Стабильный выпуск Microsoft.ML.Tokenizers ожидается вместе с выпуском .net 9.0 (ноябрь 2024 г.). Инструкции по миграции можно найти по адресу https://github.com/dotnet/machinelearning/blob/main/docs/code/microsoft-ml-tokenizers-migration-guide.md.
Чтобы установить Sharptoken, используйте диспетчер пакетов Nuget:
Install-Package SharpTokenИли, если вы предпочитаете использовать CLI .NET:
dotnet add package SharpTokenДля получения дополнительной информации посетите страницу пакета Nuget.
Чтобы использовать Sharptoken в вашем проекте, сначала импортируйте библиотеку:
using SharpToken ;Далее создайте экземпляр GptCoding, указав желаемое кодирование или модель:
// Get encoding by encoding name
var encoding = GptEncoding . GetEncoding ( " cl100k_base " ) ;
// Get encoding by model name
var encoding = GptEncoding . GetEncodingForModel ( " gpt-4 " ) ;Затем вы можете использовать метод Encode, чтобы кодировать строку:
var encoded = encoding . Encode ( " Hello, world! " ) ; // Output: [9906, 11, 1917, 0]И используйте метод декодирования, чтобы декодировать кодированные токены:
var decoded = encoding . Decode ( encoded ) ; // Output: "Hello, world!"Шарптокен также обеспечивает высокий метод подсчета производительности. Полезно проверить размер подсказки перед отправкой его в LLM или использовать его в текстовой пленке/кусочке для тряпки.
var count = encoding . CountTokens ( " Hello, world! " ) ; // Output: 4 Shpptoken в настоящее время поддерживает следующие модели:
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 " ) ;Помимо указания прямых имен моделей, Shptoken также предоставляет функциональность для картирования имен моделей на основе конкретных префиксов. Это позволяет пользователям получать кодирование на основе префикса модели.
Вот текущие поддерживаемые префиксы и их соответствующие кодировки:
| Модель префикса | Кодирование |
|---|---|
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 .
Когда вы кодируете строку, используя метод Encode, возвращаемое значение представляет собой список целых чисел, которые представляют токены в указанном кодировании. Эти токены являются компактным способом представления входного текста и могут быть более эффективно обрабатываться различными алгоритмами.
Например, кодирование текста "Привет, мир!" Использование кодирования CL100K_BASE может привести к следующему списку целых чисел:
var encoded = cl100kBaseEncoding . Encode ( " Hello world! " ) ; // Output: [9906, 1917, 0] Затем вы можете использовать метод Decode для преобразования этих токенизированных целочисленных значений обратно в исходный текст:
var decoded = cl100kBaseEncoding . Decode ( encoded ) ; // Output: "Hello world!" С Sharptoken вы можете беспрепятственно переключаться между различными кодировками, чтобы найти тот, который лучше всего соответствует вашим потребностям. Просто не забывайте использовать одну и ту же кодирование как для методов Encode , так и Decode , чтобы обеспечить точные результаты.
Шарптокен позволяет указать пользовательские наборы разрешенных специальных токенов при кодировании текста. Для этого передайте хешсет, содержащий допустимые специальные токены в качестве параметра методу кода:
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> содержащий запрещенные специальные токены в качестве параметра методу Encode:
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 включает в себя набор тестовых случаев в файле testplans.txt, чтобы обеспечить его совместимость с библиотекой Python Tiktoken. Эти тестовые примеры подтверждают функциональность и поведение Sharptoken, обеспечивая надежную ссылку для разработчиков. Запуск модульных тестов и проверка тестовых примеров помогает поддерживать согласованность между библиотекой C# Sharptoken и оригинальной реализацией Python.
Шарптокен - самая быстрая библиотека с самыми низкими ассигнованиями!
[ 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 МБ |
| Mltokenizers | .NET 6.0 | .NET 6.0 | 95,75 мс | 1,374 мс | 1,147 мс | 95,54 мс | 10500.0000 | - | 126,19 МБ |
| Mltokenizers | .Net Framework 4.7.1 | .Net Framework 4.7.1 | 291,77 мс | 5,811 мс | 11.195 мс | 291,64 мс | 21000.0000 | - | 127,33 МБ |
| Шарптокен | .NET 8.0 | .NET 8.0 | 87,78 мс | 1,700 мс | 1,590 мс | 87,34 мс | 1000.0000 | - | 22,13 МБ |
| Шарптокен | .NET 6.0 | .NET 6.0 | 128,84 мс | 1,718 мс | 1,607 мс | 128,17 мс | 16250.0000 | 500.0000 | 196,31 МБ |
| Шарптокен | .Net Framework 4.7.1 | .Net Framework 4.7.1 | 356,21 мс | 6,843 мс | 10,854 мс | 355,09 мс | 34000.0000 | 1000.0000 | 204,39 МБ |
| Tokenizerlib | .NET 8.0 | .NET 8.0 | 109,26 мс | 2.082 мс | 4,482 мс | 107,90 мс | 18200.0000 | 600.0000 | 217,82 МБ |
| Tokenizerlib | .NET 6.0 | .NET 6.0 | 126,16 мс | 2,959 мс | 8,630 мс | 122,34 мс | 18000.0000 | 500.0000 | 217,82 МБ |
| Tokenizerlib | .Net Framework 4.7.1 | .Net Framework 4.7.1 | 374,71 мс | 7,374 мс | 16.794 MS | 370,12 мс | 40000.0000 | 1000.0000 | 243,79 МБ |
| Tiktokensharp | .NET 8.0 | .NET 8.0 | 177,34 мс | 3,506 мс | 8,797 мс | 174,98 мс | 28000.0000 | 1000.0000 | 338,98 МБ |
| Tiktokensharp | .NET 6.0 | .NET 6.0 | 196,17 мс | 3,912 мс | 8,422 мс | 195,52 мс | 26000.0000 | 666.6667 | 313,26 МБ |
| Tiktokensharp | .Net Framework 4.7.1 | .Net Framework 4.7.1 | 488,22 мс | 9.696 MS | 15,931 мс | 487,17 мс | 63000.0000 | 1000.0000 | 378,31 МБ |
Shpptoken - это чрезвычайно, оптимизированная на Net8.0. Он использует современные инструкции процессора с мультибитом и почти не распределяет кучу.
Все основные методы были протестированы на большом и небольшом входном тексте.
Входные данные:
SmallText : 453 B (текст/равнина)LargeText : 51 кб (текст/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 США | 0,4244 США | 0,4359 США | 0,28 | 0,01 | 696 б | 0,02 |
| Encode_largetext | 4542,505 США | 87.7988 США | 104.5182 США | 0,24 | 0,01 | 155547 б | 0,03 |
| Decode_smalltext | 1.623 США | 0,0324 США | 0,0373 США | 0,44 | 0,02 | 2320 б | 0,98 |
| Decode_largetext | 454.570 США | 6.8980 США | 6.4524 США | 0,80 | 0,02 | 286979 б | 1,00 |
| Counttokens_smalltext | 22.008 США | 0,1165 США | 0,0909 США | 0,28 | 0,00 | 184 б | 0,005 |
| Counttokens_largetext | 4,231,353 США | 14.5157 США | 11.3329 США | 0,23 | 0,00 | 195 б | 0,000 |
| .NET 6.0 | |||||||
| Encode_smallText | 36.370 США | 0,7178 США | 1.0962 США | 0,45 | 0,02 | 37344 б | 0,91 |
| Encode_largetext | 11,213.070 США | 219.6291 США | 269.7243 США | 0,59 | 0,02 | 5062574 б | 0,91 |
| Decode_smalltext | 2.588 США | 0,0394 США | 0,0350 США | 0,70 | 0,02 | 2320 б | 0,98 |
| Decode_largetext | 489,467 США | 8.9195 США | 8.3433 США | 0,86 | 0,02 | 286985 б | 1,00 |
| Counttokens_smalltext | 34,758 США | 0,2027 США | 0,1896 США | 0,45 | 0,01 | 36832 б | 0,907 |
| Counttokens_largetext | 11 252,083 США | 215.8912 США | 212.0340 США | 0,61 | 0,01 | 4907169 б | 0,907 |
| .Net Framework 4.7.1 | |||||||
| Encode_smallText | 79,947 США | 1.5621 США | 3.0097 США | 1,00 | 0,00 | 41138 б | 1,00 |
| Encode_largetext | 18 961,252 США | 253.1816 США | 236.8262 США | 1,00 | 0,00 | 5567685 б | 1,00 |
| Decode_smalltext | 3.723 США | 0,0728 США | 0,0997 США | 1,00 | 0,00 | 2375 б | 1,00 |
| Decode_largetext | 570.787 США | 11.0356 США | 11.8080 США | 1,00 | 0,00 | 287496 б | 1,00 |
| Counttokens_smalltext | 77.521 США | 1.0802 США | 0,9020 США | 1,00 | 0,00 | 40616 б | 1.000 |
| Counttokens_largetext | 18 485,392 США | 313.5834 США | 277.9836 США | 1,00 | 0,00 | 5413237 б | 1.000 |
Если вы сталкиваетесь с какими -либо проблемами или у вас есть предложения по улучшению, не стесняйтесь открывать проблему или отправить запрос на привлечение в хранилище проекта.
Надеюсь, вы найдете Sharptoken полезным для ваших проектов и приветствуйте любые отзывы, которые у вас могут иметь.