
Sharptoken هي مكتبة C# تعمل كميناء لمكتبة Python Tiktoken. يوفر وظيفة لترميز وفك تشفير الرموز باستخدام الترميزات المستندة إلى GPT. تم تصميم هذه المكتبة لـ .NET 6 و .NET 8 و .NET Standard 2.0 ، مما يجعلها متوافقة مع مجموعة واسعة من الأطر.
مهم
تمت إضافة الوظيفة في SharpToken إلى Microsoft.ML.Tokenizers . Microsoft.ML.Tokenizers هي مكتبة Tokenizer التي يتم تطويرها من قبل فريق .NET والمضي قدمًا ، المكان المركزي لتطوير Tokenizer في .NET. باستخدام Microsoft.ML.Tokenizers ، يجب أن ترى تحسين الأداء على تطبيقات مكتبة Tokenizer الحالية ، بما في ذلك 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 Package Manager:
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 أو لاستخدامه في Sextsplitter/chunker لـ RAC.
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 مجموعة من حالات الاختبار في ملف testplans.txt لضمان توافقه مع مكتبة Python Tiktoken. تتحقق حالات الاختبار هذه من وظائف وسلوك 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 ميغابايت |
| 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 ميغابايت |
| Sharptoken | .NET 8.0 | .NET 8.0 | 87.78 مللي ثانية | 1.700 مللي ثانية | 1.590 مللي ثانية | 87.34 مللي ثانية | 1000.0000 | - | 22.13 ميغابايت |
| Sharptoken | .NET 6.0 | .NET 6.0 | 128.84 مللي ثانية | 1.718 مللي ثانية | 1.607 مللي ثانية | 128.17 مللي ثانية | 16250.0000 | 500.0000 | 196.31 ميغابايت |
| Sharptoken | .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 مللي ثانية | 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 مللي ثانية | 15.931 مللي ثانية | 487.17 مللي ثانية | 63000.0000 | 1000.0000 | 378.31 ميغابايت |
تم تحسين أداء Sharptoken بشكل خاص على Net8.0. يستخدم تعليمات وحدة المعالجة المركزية المتعددة الحديثة وعدم وجود تخصيصات كومة تقريبًا.
تم اختبار جميع الطرق الأساسية على نص إدخال كبير وصغير.
المدخلات:
SmallText : 453 ب (نص/عادي)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 مفيدة لمشاريعك وترحب بأي تعليقات قد تكون لديك.