Với một chuỗi văn bản (ví dụ, "tiktoken is great!"
) và một mã hóa (ví dụ, "cl100k_base"
), trình phân tích cú pháp có thể chia chuỗi văn bản thành một danh sách các mã thông báo (ví dụ, ["t", "ik", "token", " is", " great", "!"]
).
Chia chuỗi văn bản thành các mã thông báo rất hữu ích vì các mô hình tài khoản Chat GPT-4 thấy văn bản dưới dạng mã thông báo. Biết có bao nhiêu mã thông báo trong một chuỗi văn bản có thể cho bạn biết (a) liệu chuỗi đó có quá dài để mô hình văn bản xử lý hay không và (b) chi phí cho một cuộc gọi API OpenAI là bao nhiêu (vì mức sử dụng được định giá theo mã thông báo).
Mã hóa
Mã hóa chỉ rõ cách văn bản được chuyển đổi thành mã thông báo. Các mô hình khác nhau sử dụng các mã hóa khác nhau.
tiktoken
hỗ trợ ba mã hóa được sử dụng bởi các mô hình OpenAI:
Xem thêm: mua tài khoản ChatGPT Plus chính hãng giá rẻ
Tên mã hóa | Mô hình OpenAI |
---|---|
cl100k_base | gpt-4 , gpt-3.5-turbo , text-embedding-ada-002 , text-embedding-3-small ,text-embedding-3-large |
p50k_base | Mô hình Codex text-davinci-002 ,text-davinci-003 |
r50k_base (hoặc gpt2 ) | Các mô hình GPT-4 nhưdavinci |
Bạn có thể lấy mã hóa cho một mô hình bằng cách sử dụng tiktoken.encoding_for_model()
như sau:
encoding = tiktoken.encoding_for_model('gpt-3.5-turbo')
Lưu ý rằng p50k_base
chúng chồng chéo đáng kể với r50k_base
, và đối với các ứng dụng không phải mã, chúng thường sẽ cung cấp cùng một mã thông báo.
Thư viện Tokenizer theo ngôn ngữ
Đối với cl100k_base
và p50k_base
mã hóa:
- Python: tiktoken
- .NET / C#: SharpToken , TiktokenSharp
- Java: jtocks
- Golang: tích tắc
- Rust: tiktoken-rs
Đối với mã hóa r50k_base
( gpt2
), trình phân tích cú pháp có sẵn ở nhiều ngôn ngữ.
- Python: tiktoken (hoặc GPT2 TokenizerFast )
- JavaScript: gpt-3-encoder
- .NET / C#: Mã thông báo GPT
- Java: gpt2-tokenizer-java
- PHP: GPT-3-Encoder-PHP
- Golang: tích tắc
- Rust: tiktoken-rs
(OpenAI không xác nhận hoặc đảm bảo bất kỳ thư viện của bên thứ ba nào.)
Chuỗi thường được mã hóa như thế nào
Trong tiếng Anh, các mã thông báo thường có độ dài từ một ký tự đến một từ (ví dụ: "t"
hoặc " great"
), mặc dù trong một số ngôn ngữ, các mã thông báo có thể ngắn hơn một ký tự hoặc dài hơn một từ. Các khoảng trắng thường được nhóm với các từ bắt đầu (ví dụ: " is"
thay vì "is "
hoặc " "
+ "is"
). Bạn có thể nhanh chóng kiểm tra cách một chuỗi được mã hóa tại OpenAI Tokenizer hoặc ứng dụng web Tiktokenizer của bên thứ ba .
Cài đặttiktoken
Nếu cần, hãy cài đặt tiktoken
bằng pip
:
%pip install --upgrade tiktoken
%pip install --upgrade openai
Nhập khẩutiktoken
import tiktoken
Tải mã hóa
Sử dụng tiktoken.get_encoding()
để tải mã hóa theo tên.
Lần đầu tiên chạy, cần phải có kết nối internet để tải xuống. Các lần chạy sau sẽ không cần kết nối internet.
encoding = tiktoken.get_encoding("cl100k_base")
Sử dụng tiktoken.encoding_for_model()
để tự động tải mã hóa chính xác cho tên mô hình nhất định.
encoding = tiktoken.encoding_for_model("gpt-3.5-turbo")
Biến văn bản thành mã thông báo vớiencoding.encode()
Phương pháp này .encode()
chuyển đổi một chuỗi văn bản thành một danh sách các số nguyên.
encoding.encode("tiktoken is great!")
[83, 1609, 5963, 374, 2294, 0]
Đếm mã thông báo bằng cách đếm độ dài của danh sách được trả về bởi .encode()
.
def num_tokens_from_string(string: str, encoding_name: str) -> int: """Returns the number of tokens in a text string.""" encoding = tiktoken.get_encoding(encoding_name) num_tokens = len(encoding.encode(string)) return num_tokens
num_tokens_from_string("tiktoken is great!", "cl100k_base")
6
Biến token thành văn bản vớiencoding.decode()
.decode()
chuyển đổi danh sách các số nguyên token thành chuỗi.
encoding.decode([83, 1609, 5963, 374, 2294, 0])
'tiktoken thật tuyệt vời!'
Cảnh báo: mặc dù .decode()
có thể áp dụng cho các mã thông báo đơn lẻ, hãy cẩn thận vì nó có thể gây mất mát đối với các mã thông báo không nằm trong ranh giới utf-8.
Đối với các mã thông báo đơn, .decode_single_token_bytes()
chuyển đổi an toàn một mã thông báo số nguyên đơn thành các byte mà nó biểu diễn.
[encoding.decode_single_token_bytes(token) for token in [83, 1609, 5963, 374, 2294, 0]]
[b't', b'ik', b'token', b' là', b' tuyệt vời', b'!']
(Dấu b
ở phía trước chuỗi cho biết chuỗi đó là chuỗi byte.)
So sánh mã hóa
Các mã hóa khác nhau khác nhau về cách chúng phân chia từ, nhóm khoảng trắng và xử lý các ký tự không phải tiếng Anh. Sử dụng các phương pháp trên, chúng ta có thể so sánh các mã hóa khác nhau trên một số chuỗi ví dụ.
def compare_encodings(example_string: str) -> None: """Prints a comparison of three string encodings.""" # print the example string print(f'\nExample string: "{example_string}"') # for each encoding, print the # of tokens, the token integers, and the token bytes for encoding_name in ["r50k_base", "p50k_base", "cl100k_base"]: encoding = tiktoken.get_encoding(encoding_name) token_integers = encoding.encode(example_string) num_tokens = len(token_integers) token_bytes = [encoding.decode_single_token_bytes(token) for token in token_integers] print() print(f"{encoding_name}: {num_tokens} tokens") print(f"token integers: {token_integers}") print(f"token bytes: {token_bytes}")
compare_encodings("antidisestablishmentarianism")
Chuỗi ví dụ: "antidisestablishmentarianism"
r50k_base: 5 token số nguyên token: [415, 29207, 44390, 3699, 1042] token byte: [b'ant', b'idis', b'establishment', b'arian', b'ism']
p50k_base: 5 token số nguyên token: [415, 29207, 44390, 3699, 1042] token byte: [b'ant', b'idis', b'establishment', b'arian', b'ism']
cl100k_base: 6 token số nguyên token: [519, 85342, 34500, 479, 8997, 2191] token byte: [b'ant', b'idis', b'establish', b'ment', b'arian', b'ism']
compare_encodings("2 + 2 = 4")
Chuỗi ví dụ: "2 + 2 = 4"
r50k_base: 5 token số nguyên token: [17, 1343, 362, 796, 604] token byte: [b'2', b' +', b' 2', b' =', b' 4']
p50k_base: 5 token số nguyên token: [17, 1343, 362, 796, 604] token byte: [b'2', b' +', b' 2', b' =', b' 4']
cl100k_base: 7 token số nguyên token: [17, 489, 220, 17, 284, 220, 19] token byte: [b'2', b' +', b' ', b'2', b' =', b' ', b'4']
compare_encodings("お誕生日おめでとう")
Chuỗi ví dụ: "お誕生日おめでとう"
r50k_base: 14 số nguyên mã thông báo: [2515, 232, 45739, 243, 37955, 33768, 98, 2515, 232, 1792, 223, 30640, 30201 , 29557] byte mã thông báo: [b '\xe3\x81', b'\x8a', b'\xe8\xaa', b'\x95', b'\xe7\x94\x9f', b'\xe6\x97', b'\xa5' , b'\xe3\x81', b'\x8a', b'\xe3\x82', b'\x81', b'\xe3\x81\xa7', b'\xe3\x81\xa8', b'\xe3\x81\x86']
p50k_base: 14 mã thông báo số nguyên mã thông báo: [2515, 232, 45739, 243, 37955, 33768, 98, 2515, 232, 1792, 223, 30640, 30201, 29557] mã thông báo byte: [b'\xe3\x81', b'\x8a', b'\xe8\xaa', b'\x95', b' \xe7\x94\x9f', b'\xe6\x97', b'\xa5', b'\xe3\x81', b'\x8a', b'\xe3\x82', b'\x81', b'\xe3\x81\xa7', b'\xe3\x81\xa8', b'\xe3\x81\x86']
cl100k_base: 9 mã thông báo số nguyên mã thông báo: [33334, 45918, 243, 21990, 9080, 33334, 62004, 16556, 78699] byte mã thông báo: [b'\xe3\x81\x8a', b'\xe8\xaa', b'\x95', b'\xe7\x94\x9f', b'\xe6\x97\xa5', b'\xe3\x81\x8a', b'\xe3\x82\x81', b'\xe3\x81\xa7', b'\xe3\x81\xa8\xe3\x81\x86']
Đếm mã thông báo cho các cuộc gọi API hoàn thành trò chuyện
Các mô hình ChatGPT sử dụng mã thông báo theo gpt-3.5-turbo
cùng gpt-4
cách như các mô hình hoàn thành cũ, nhưng do định dạng dựa trên tin nhắn nên việc đếm số lượng mã thông báo sẽ được sử dụng trong một cuộc trò chuyện trở nên khó khăn hơn.
Dưới đây là một hàm ví dụ để đếm mã thông báo cho các tin nhắn được truyền tới gpt-3.5-turbo
hoặc gpt-4
.
Lưu ý rằng cách chính xác mà các mã thông báo được đếm từ tin nhắn có thể thay đổi tùy theo từng mô hình. Hãy coi số đếm từ hàm bên dưới là ước tính, không phải là sự đảm bảo vĩnh cửu.
Đặc biệt, các yêu cầu sử dụng hàm tùy chọn đầu vào sẽ sử dụng thêm mã thông báo ngoài các ước tính được tính toán bên dưới.
def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613"): """Return the number of tokens used by a list of messages.""" try: encoding = tiktoken.encoding_for_model(model) except KeyError: print("Warning: model not found. Using cl100k_base encoding.") encoding = tiktoken.get_encoding("cl100k_base") if model in { "gpt-3.5-turbo-0613", "gpt-3.5-turbo-16k-0613", "gpt-4-0314", "gpt-4-32k-0314", "gpt-4-0613", "gpt-4-32k-0613", }: tokens_per_message = 3 tokens_per_name = 1 elif model == "gpt-3.5-turbo-0301": tokens_per_message = 4 # every message follows <|start|>{role/name}\n{content}<|end|>\n tokens_per_name = -1 # if there's a name, the role is omitted elif "gpt-3.5-turbo" in model: print("Warning: gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613.") return num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613") elif "gpt-4" in model: print("Warning: gpt-4 may update over time. Returning num tokens assuming gpt-4-0613.") return num_tokens_from_messages(messages, model="gpt-4-0613") else: raise NotImplementedError( f"""num_tokens_from_messages() is not implemented for model {model}.""" ) num_tokens = 0 for message in messages: num_tokens += tokens_per_message for key, value in message.items(): num_tokens += len(encoding.encode(value)) if key == "name": num_tokens += tokens_per_name num_tokens += 3 # every reply is primed with <|start|>assistant<|message|> return num_tokens
# let's verify the function above matches the OpenAI API response
from openai import OpenAI
import os
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY", ""))
example_messages = [ { "role": "system", "content": "You are a helpful, pattern-following assistant that translates corporate jargon into plain English.", }, { "role": "system", "name": "example_user", "content": "New synergies will help drive top-line growth.", }, { "role": "system", "name": "example_assistant", "content": "Things working well together will increase revenue.", }, { "role": "system", "name": "example_user", "content": "Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage.", }, { "role": "system", "name": "example_assistant", "content": "Let's talk later when we're less busy about how to do better.", }, { "role": "user", "content": "This late pivot means we don't have time to boil the ocean for the client deliverable.", },
]
for model in [ "gpt-3.5-turbo-0301", "gpt-3.5-turbo-0613", "gpt-3.5-turbo", "gpt-4-0314", "gpt-4-0613", "gpt-4", ]: print(model) # example token count from the function defined above print(f"{num_tokens_from_messages(example_messages, model)} prompt tokens counted by num_tokens_from_messages().") # example token count from the OpenAI API response = client.chat.completions.create(model=model, messages=example_messages, temperature=0, max_tokens=1) print(f'{response.usage.prompt_tokens} prompt tokens counted by the OpenAI API.')
gpt-3.5-turbo Cảnh báo: gpt-3.5-turbo có thể cập nhật theo thời gian. Trả về num mã thông báo giả sử gpt-3.5-turbo-0613. 129 mã thông báo nhắc nhở được đếm bởi num_tokens_from_messages(). 129 mã thông báo nhắc nhở được đếm bởi OpenAI API.
gpt-4-0314 129 mã thông báo nhắc nhở được đếm bởi num_tokens_from_messages(). 129 mã thông báo nhắc nhở được đếm bởi OpenAI API.
gpt-4-0613 129 mã thông báo nhắc nhở được đếm bởi num_tokens_from_messages(). 129 mã thông báo nhắc nhở được đếm bởi OpenAI API.
gpt-4 Cảnh báo: gpt-4 có thể cập nhật theo thời gian. Trả về num mã thông báo giả sử gpt-4-0613. 129 mã thông báo nhắc nhở được đếm bởi num_tokens_from_messages(). 129 mã thông báo nhắc nhở được đếm bởi OpenAI API.