
Sharpoken เป็นไลบรารี C# ที่ทำหน้าที่เป็นพอร์ตของห้องสมุด Python Tiktoken มันมีฟังก์ชั่นสำหรับการเข้ารหัสและถอดรหัสโทเค็นโดยใช้การเข้ารหัสแบบใช้ GPT ห้องสมุดนี้สร้างขึ้นสำหรับ. NET 6, .NET 8 และ. NET Standard 2.0 ทำให้เข้ากันได้กับเฟรมเวิร์กที่หลากหลาย
สำคัญ
ฟังก์ชั่นใน SharpToken ได้รับการเพิ่มลงใน Microsoft.ML.Tokenizers Microsoft.ML.Tokenizers เป็นห้องสมุดโทเคนิเซอร์ที่ได้รับการพัฒนาโดยทีม. NET และก้าวไปข้างหน้าซึ่งเป็นศูนย์กลางของการพัฒนา Tokenizer ใน. NET ด้วยการใช้ Microsoft.ML.Tokenizers คุณควรเห็นประสิทธิภาพที่ดีขึ้นกว่าการใช้งาน Library Tokenizer ที่มีอยู่รวมถึง SharpToken คาดว่าจะมีการเปิดตัว Microsoft.ML.Tokenizers ที่เสถียรพร้อมกับการเปิดตัว. NET 9.0 (พฤศจิกายน 2024) คำแนะนำสำหรับการย้ายถิ่นสามารถดูได้ที่ https://github.com/dotnet/machinelearning/blob/main/docs/code/microsoft-ml-tokenizers-migration-guide.md
ในการติดตั้ง Sharpoken ให้ใช้ NuGet Package Manager:
Install-Package SharpTokenหรือถ้าคุณต้องการใช้. NET CLI:
dotnet add package SharpTokenสำหรับข้อมูลเพิ่มเติมโปรดเยี่ยมชมหน้าแพ็คเกจ NUGET
หากต้องการใช้ Sharpoken ในโครงการของคุณก่อนนำเข้าห้องสมุด:
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!"Sharpoken ยังมีวิธีการนับประสิทธิภาพสูง มันมีประโยชน์ในการตรวจสอบขนาดพรอมต์ก่อนที่จะส่งไปยัง LLM หรือใช้ใน textsplitter/chunker สำหรับ RAG
var count = encoding . CountTokens ( " Hello, world! " ) ; // Output: 4 ปัจจุบัน Sharpoken รองรับรุ่นต่อไปนี้:
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 " ) ;นอกเหนือจากการระบุชื่อโมเดลโดยตรง Sharpoken ยังให้ฟังก์ชั่นการทำงานกับชื่อโมเดลแผนที่ตามคำนำหน้าเฉพาะ สิ่งนี้ช่วยให้ผู้ใช้สามารถดึงการเข้ารหัสตามคำนำหน้าของรุ่น
นี่คือคำนำหน้ารองรับปัจจุบันและการเข้ารหัสที่เกี่ยวข้อง:
| คำนำหน้าแบบจำลอง | การเข้ารหัส |
|---|---|
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!" ด้วย Sharpoken คุณสามารถสลับระหว่างการเข้ารหัสที่แตกต่างกันได้อย่างราบรื่นเพื่อค้นหาสิ่งที่เหมาะสมกับความต้องการของคุณมากที่สุด เพียงจำไว้ว่าให้ใช้การเข้ารหัสเดียวกันสำหรับทั้งวิธี Encode และ Decode เพื่อให้แน่ใจว่าผลลัพธ์ที่แม่นยำ
Sharpoken ช่วยให้คุณสามารถระบุชุดโทเค็นพิเศษที่ได้รับอนุญาตเมื่อเข้ารหัสข้อความ ในการทำเช่นนี้ให้ผ่าน Hashset ที่มีโทเค็นพิเศษที่อนุญาตเป็นพารามิเตอร์ไปยังวิธีการเข้ารหัส:
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 จะถูกโยนทิ้งเพราะข้อความอินพุตมีโทเค็นพิเศษที่ไม่ได้รับอนุญาต
Sharpoken รวมชุดของกรณีทดสอบในไฟล์ testplans.txt เพื่อให้แน่ใจว่าเข้ากันได้กับไลบรารี Python Tiktoken กรณีทดสอบเหล่านี้ตรวจสอบการทำงานและพฤติกรรมของ Sharpoken ซึ่งให้การอ้างอิงที่เชื่อถือได้สำหรับนักพัฒนา การรันการทดสอบหน่วยและตรวจสอบกรณีทดสอบช่วยรักษาความสอดคล้องระหว่างไลบรารี C# Sharpoken และการใช้งาน Python ดั้งเดิม
Sharpoken เป็นห้องสมุดที่เร็วที่สุดที่มีการจัดสรรต่ำสุด!
[ 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 ms | 1.143 ms | 1.123 ms | 60.45 ms | 1,000.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 |
| Sharpoken | .NET 8.0 | .NET 8.0 | 87.78 ms | 1.700 ms | 1.590 ms | 87.34 ms | 1,000.0000 | - | 22.13 MB |
| Sharpoken | .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 |
| Sharpoken | .NET Framework 4.7.1 | .NET Framework 4.7.1 | 356.21 ms | 6.843 ms | 10.854 ms | 355.09 ms | 34000.0000 | 1,000.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 | 1,000.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 | 1,000.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 | 1,000.0000 | 378.31 MB |
Sharpoken เป็นประสิทธิภาพที่ได้รับการปรับให้เหมาะสมบน Net8.0 มันใช้คำแนะนำ CPU แบบ multibyte ที่ทันสมัยและแทบจะไม่มีการจัดสรรกอง
วิธีการหลักทั้งหมดได้รับการทดสอบบนข้อความอินพุตขนาดใหญ่และขนาดเล็ก
อินพุต:
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 เรา | 0.4244 US | 0.4359 เรา | 0.28 | 0.01 | 696 b | 0.02 |
| ENCODE_LARGETEXT | 4,542.505 เรา | 87.7988 เรา | 104.5182 เรา | 0.24 | 0.01 | 155547 B | 0.03 |
| decode_smalltext | 1.623 เรา | 0.0324 US | 0.0373 เรา | 0.44 | 0.02 | 2320 b | 0.98 |
| decode_largetext | 454.570 เรา | 6.8980 เรา | 6.4524 เรา | 0.80 | 0.02 | 286979 B | 1.00 |
| counttokens_smalltext | 22.008 เรา | 0.1165 เรา | 0.0909 US | 0.28 | 0.00 | 184 B | 0.005 |
| counttokens_largetext | 4,231.353 เรา | 14.5157 เรา | 11.3329 เรา | 0.23 | 0.00 | 195 b | 0.000 |
| .NET 6.0 | |||||||
| ENCODE_SMALLTEXT | 36.370 เรา | 0.7178 US | 1.0962 เรา | 0.45 | 0.02 | 37344 B | 0.91 |
| ENCODE_LARGETEXT | 11,213.070 เรา | 219.6291 เรา | 269.7243 เรา | 0.59 | 0.02 | 5062574 B | 0.91 |
| decode_smalltext | 2.588 เรา | 0.0394 เรา | 0.0350 US | 0.70 | 0.02 | 2320 b | 0.98 |
| decode_largetext | 489.467 เรา | 8.9195 เรา | 8.3433 เรา | 0.86 | 0.02 | 286985 B | 1.00 |
| counttokens_smalltext | 34.758 เรา | 0.2027 US | 0.1896 เรา | 0.45 | 0.01 | 36832 b | 0.907 |
| counttokens_largetext | 11,252.083 US | 215.8912 เรา | 212.0340 เรา | 0.61 | 0.01 | 4907169 B | 0.907 |
| .NET Framework 4.7.1 | |||||||
| ENCODE_SMALLTEXT | 79.947 เรา | 1.5621 US | 3.0097 เรา | 1.00 | 0.00 | 41138 b | 1.00 |
| ENCODE_LARGETEXT | 18,961.252 เรา | 253.1816 เรา | 236.8262 เรา | 1.00 | 0.00 | 5567685 B | 1.00 |
| decode_smalltext | 3.723 เรา | 0.0728 US | 0.0997 เรา | 1.00 | 0.00 | 2375 b | 1.00 |
| decode_largetext | 570.787 เรา | 11.0356 เรา | 11.8080 เรา | 1.00 | 0.00 | 287496 B | 1.00 |
| counttokens_smalltext | 77.521 เรา | 1.0802 US | 0.9020 US | 1.00 | 0.00 | 40616 B | 1.000 |
| counttokens_largetext | 18,485.392 เรา | 313.5834 เรา | 277.9836 เรา | 1.00 | 0.00 | 5413237 B | 1.000 |
หากคุณพบปัญหาใด ๆ หรือมีข้อเสนอแนะสำหรับการปรับปรุงโปรดเปิดปัญหาหรือส่งคำขอดึงในที่เก็บของโครงการ
หวังว่าคุณจะพบว่า Sharpoken มีประโยชน์สำหรับโครงการของคุณและยินดีต้อนรับข้อเสนอแนะใด ๆ ที่คุณอาจมี