پکیج tiktoken یک توکن ساز سریع و open source است که توسط OpenAI توسعه پیدا کرده است. با دادن یک رشته متن (مثلاً، “tiktoken is great!”) و یک encoding (مثلاً، “cl100k_base”)، یک توکن ساز می تواند رشته متن را به یک لیست از توکن ها تقسیم کند (مثلاً، [“t”, “ik”, “token”, " is", " great", “!”]).
تقسیم کردن رشته های متن به توکن ها مفید است زیرا مدل های GPT متن را به صورت توکن می بینند. دانستن تعداد توکن های موجود در یک رشته متن می تواند به شما بگوید (الف) آیا رشته برای پردازش توسط مدل بیش از حد مجاز طولانی است و (ب) فراخوانی API مدل چقدر هزینه دارد (زیرا استفاده از آن بر اساس توکن قیمت گذاری می شود).
توجه: ورودیهای داده شده و خروجیهای تولید شده توسط مدل در این مثال به زبان انگلیسی هستند. برای تولید خروجی به زبان فارسی٬ کافیست از مدل بخواهید که خروجی را به زبان فارسی تولید کند.
Encodings #
یک encoding مشخص می کند که چگونه متن به توکن تبدیل می شود. مدل های مختلف از encoding های مختلفی استفاده می کنند. tiktoken سه encoding را که توسط مدل های OpenAI استفاده می شوند پشتیبانی می کند:
Encoding name | OpenAI models |
---|---|
cl100k_base | gpt-4-turbo , gpt-3.5-turbo , text-embedding-ada-002 , text-embedding-3-small , text-embedding-3-large |
p50k_base | Codex models, text-davinci-002 , text-davinci-003 |
r50k_base | GPT-3 models like davinci |
شما می توانید encoding را برای یک مدل با استفاده از tiktoken.encoding_for_model()
به شکل زیر بازیابی کنید:
1encoding = tiktoken.encoding_for_model('gpt-3.5-turbo')
توجه داشته باشید که p50k_base به طور قابل توجهی با r50k_base همپوشانی دارد و برای برنامه های غیر کد، معمولاً همان توکن ها را ارائه می دهند.
کتابخانههای tiktoken برای زبانهای برنامهنویسی مختلف #
برای encoding های cl100k_base و p50k_base:
- Python: tiktoken
- NET / C#: SharpToken, TiktokenSharp
- Java: jtokkit
- Go: tiktoken-go
- Rust: tiktoken-rs
متون چطوری به توکنها تبدیل میشوند؟ #
در انگلیسی، طول توکن ها معمولاً از یک کاراکتر تا یک کلمه متغیرند (مثلاً، “t” یا " great")، اگرچه در برخی زبان ها توکن ها می توانند کوتاه تر از یک کاراکتر یا بلندتر از یک کلمه باشند.
فضاهای خالی معمولاً با شروع کلمات دسته بندی می شوند (مثلاً، " is" به جای “is " یا " “+“is”).
برای مشاهده ساخت رشته ای از توکنها از روی یک متن میتوانید از Tiktokenizer استفاده کنید.
استفاده از پکیج tiktoken در پایتون #
در صورت نیاز، tiktoken را با pip نصب کنید
برای بارگذاری یک encoding بر اساس نام، از tiktoken.get_encoding()
استفاده کنید. اولین باری که این کد را اجرا می کنید، نیاز به اتصال به اینترنت برای دانلود آن دارید. اجراهای بعدی نیازی به اتصال به اینترنت ندارند.
برای بارگذاری خودکار encoding صحیح
از tiktoken.encoding_for_model()
استفاده کنید.
1encoding = tiktoken.encoding_for_model("gpt-3.5-turbo")
حالا میتوانید یک متن را به توکن تبدیل کنید.
تعداد توکن ها را با شمارش طول لیست بازگردانده شده توسط .encode()
بشمارید.
1def num_tokens_from_string(string: str, encoding_name: str) -> int:
2 """Returns the number of tokens in a text string."""
3 encoding = tiktoken.get_encoding(encoding_name)
4 num_tokens = len(encoding.encode(string))
5 return num_tokens
6
7
8num_tokens_from_string("tiktoken is great!", "cl100k_base")
9
10-> 6
برای تبدیل توکن ها به متن از encoding.decode()
استفاده کنید.
تابع .decode_single_token_bytes()
به طور ایمن یک توکن عدد صحیح تکی را به بایت هایی که نماینده آن است تبدیل می کند.
1[encoding.decode_single_token_bytes(token) for token in [83, 1609, 5963, 374, 2294, 0]]
2
3-> [b't', b'ik', b'token', b' is', b' great', b'!']
شمارش توکنها برای فراخوانی Chat Completions API #
در زیر یک تابع نمونه برای شمارش توکنها برای پیامهای ارسالی به gpt-3.5-turbo یا gpt-4-turbo وجود دارد. توجه داشته باشید که روش دقیق شمارش توکنها از پیامها ممکن است از مدل به مدل تغییر کند. شمارشهای حاصل از تابع زیر را یک تخمین در نظر بگیرید، نه یک ضمانت. به خصوص، درخواستهایی که از Function call استفاده میکنند، توکنهای اضافی را بر روی تخمینهای محاسبه شده در زیر مصرف خواهند کرد.
1def num_tokens_from_messages(messages, model="gpt-3.5-turbo"):
2 """Return the number of tokens used by a list of messages."""
3 try:
4 encoding = tiktoken.encoding_for_model(model)
5 except KeyError:
6 print("Warning: model not found. Using cl100k_base encoding.")
7 encoding = tiktoken.get_encoding("cl100k_base")
8 if model in {
9 "gpt-3.5-turbo-0613",
10 "gpt-3.5-turbo-16k-0613",
11 "gpt-4-0314",
12 "gpt-4-32k-0314",
13 "gpt-4-0613",
14 "gpt-4-32k-0613",
15 }:
16 tokens_per_message = 3
17 tokens_per_name = 1
18 elif model == "gpt-3.5-turbo-0301":
19 tokens_per_message = 4 # every message follows <|start|>{role/name}\n{content}<|end|>\n
20 tokens_per_name = -1 # if there's a name, the role is omitted
21 elif "gpt-3.5-turbo" in model:
22 print("Warning: gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613.")
23 return num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613")
24 elif "gpt-4" in model:
25 print("Warning: gpt-4 may update over time. Returning num tokens assuming gpt-4-0613.")
26 return num_tokens_from_messages(messages, model="gpt-4-0613")
27 else:
28 raise NotImplementedError(
29 f"""num_tokens_from_messages() is not implemented for model {model}. See https://github.com/openai/openai-python/blob/main/chatml.md for information on how messages are converted to tokens."""
30 )
31 num_tokens = 0
32 for message in messages:
33 num_tokens += tokens_per_message
34 for key, value in message.items():
35 num_tokens += len(encoding.encode(value))
36 if key == "name":
37 num_tokens += tokens_per_name
38 num_tokens += 3 # every reply is primed with <|start|>assistant<|message|>
39 return num_tokens
برای اجرای کدهای زیر ابتدا باید یک کلید API را از طریق پنل کاربری گیلاس تولید کنید. برای این کار ابتدا یک حساب کاربری جدید بسازید یا اگر صاحب حساب کاربری هستید وارد پنل کاربری خود شوید. سپس، به صفحه کلید API بروید و با کلیک روی دکمه “ساخت کلید API” یک کلید جدید برای دسترسی به Gilas API بسازید.
1# let's verify the function above matches the Gilas API response
2
3from openai import OpenAI
4import os
5
6client = OpenAI(
7 api_key=os.environ.get(("GILAS_API_KEY", "<کلید API خود را اینجا بسازید https://dashboard.gilas.io/apiKey>")),
8 base_url="https://api.gilas.io/v1/" # Gilas APIs
9)
10
11example_messages = [
12 {
13 "role": "system",
14 "content": "You are a helpful, pattern-following assistant that translates corporate jargon into plain English.",
15 },
16 {
17 "role": "system",
18 "name": "example_user",
19 "content": "New synergies will help drive top-line growth.",
20 },
21 {
22 "role": "system",
23 "name": "example_assistant",
24 "content": "Things working well together will increase revenue.",
25 },
26 {
27 "role": "system",
28 "name": "example_user",
29 "content": "Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage.",
30 },
31 {
32 "role": "system",
33 "name": "example_assistant",
34 "content": "Let's talk later when we're less busy about how to do better.",
35 },
36 {
37 "role": "user",
38 "content": "This late pivot means we don't have time to boil the ocean for the client deliverable.",
39 },
40]
41
42for model in [
43 "gpt-3.5-turbo-0301",
44 "gpt-3.5-turbo-0613",
45 "gpt-3.5-turbo",
46 "gpt-4-0314",
47 "gpt-4-0613",
48 "gpt-4",
49 ]:
50 print(model)
51 # example token count from the function defined above
52 print(f"{num_tokens_from_messages(example_messages, model)} prompt tokens counted by num_tokens_from_messages().")
53 # example token count from the Gilas API
54 response = client.chat.completions.create(model=model,
55 messages=example_messages,
56 temperature=0,
57 max_tokens=1)
58 print(f'{response.usage.prompt_tokens} prompt tokens counted by the Gilas API.')
59 print()
خروجی: