简体中文
Openai's Tiktoken in Go.
Tiktoken - быстрый токенизер BPE для использования с моделями Openai.
Это порт оригинального Tiktoken.
go get github.com/pkoukk/tiktoken-goTiktoken-go имеет тот же механизм кеша, что и оригинальная библиотека Tiktoken.
Вы можете установить каталог кэша, используя переменную среды tiktoken_cache_dir.
Как только эта переменная установлена, Tiktoken-Go будет использовать этот каталог для кэширования словаря токена.
Если вы не установите эту переменную среды, Tiktoken-Go будет загружать словарь каждый раз, когда вы инициализируете кодирование в первый раз.
Если вы не хотите использовать кэш или загружать словарь каждый раз, вы можете использовать альтернативный загрузчик BPE.
Просто позвоните tiktoken.SetBpeLoader прежде чем называть tiktoken.GetEncoding или tiktoken.EncodingForModel .
BpeLoader - это интерфейс, вы можете реализовать свой собственный загрузчик BPE, реализуя этот интерфейс.
Автономный загрузчик BPE загружает словарь BPE из файлов Embed, он помогает, если вы не хотите загружать словарь во время выполнения.
Из -за размера словаря BPE этот погрузчик находится в другом проекте.
Включите, если вам требуется этот загрузчик: tiktoken_loader
package main
import (
"fmt"
"github.com/pkoukk/tiktoken-go"
)
func main () {
text := "Hello, world!"
encoding := "cl100k_base"
// if you don't want download dictionary at runtime, you can use offline loader
// tiktoken.SetBpeLoader(tiktoken_loader.NewOfflineLoader())
tke , err := tiktoken . GetEncoding ( encoding )
if err != nil {
err = fmt . Errorf ( "getEncoding: %v" , err )
return
}
// encode
token := tke . Encode ( text , nil , nil )
//tokens
fmt . Println (( token ))
// num_tokens
fmt . Println ( len ( token ))
} package main
import (
"fmt"
"github.com/pkoukk/tiktoken-go"
)
func main () {
text := "Hello, world!"
encoding := "gpt-3.5-turbo"
tkm , err := tiktoken . EncodingForModel ( encoding )
if err != nil {
err = fmt . Errorf ( "getEncoding: %v" , err )
return
}
// encode
token := tkm . Encode ( text , nil , nil )
// tokens
fmt . Println ( token )
// num_tokens
fmt . Println ( len ( token ))
}Ниже приведен пример функции для подсчета токенов для сообщений, передаваемых GPT-3.5-Turbo или GPT-4.
Следующий код был написан на основе примеров Openai-Cookbook в Wednesday, 28 June 2023 .
Обратите внимание, что метод расчета токена для сообщения может измениться в любое время, поэтому этот код не обязательно может быть применим в будущем.
Если вам нужен точный расчет, пожалуйста, обратитесь к официальной документации.
Если вы обнаружите, что этот код больше не применим, пожалуйста, не стесняйтесь отправлять PR или проблему.
package main
import (
"fmt"
"github.com/pkoukk/tiktoken-go"
"github.com/sashabaranov/go-openai"
)
// OpenAI Cookbook: https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb
func NumTokensFromMessages ( messages []openai. ChatCompletionMessage , model string ) ( numTokens int ) {
tkm , err := tiktoken . EncodingForModel ( model )
if err != nil {
err = fmt . Errorf ( "encoding for model: %v" , err )
log . Println ( err )
return
}
var tokensPerMessage , tokensPerName int
switch model {
case "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" :
tokensPerMessage = 3
tokensPerName = 1
case "gpt-3.5-turbo-0301" :
tokensPerMessage = 4 // every message follows <|start|>{role/name}n{content}<|end|>n
tokensPerName = - 1 // if there's a name, the role is omitted
default :
if strings . Contains ( model , "gpt-3.5-turbo" ) {
log . Println ( "warning: gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613." )
return NumTokensFromMessages ( messages , "gpt-3.5-turbo-0613" )
} else if strings . Contains ( model , "gpt-4" ) {
log . Println ( "warning: gpt-4 may update over time. Returning num tokens assuming gpt-4-0613." )
return NumTokensFromMessages ( messages , "gpt-4-0613" )
} else {
err = fmt . Errorf ( "num_tokens_from_messages() is not implemented for model %s. See https://github.com/openai/openai-python/blob/main/chatml.md for information on how messages are converted to tokens." , model )
log . Println ( err )
return
}
}
for _ , message := range messages {
numTokens += tokensPerMessage
numTokens += len ( tkm . Encode ( message . Content , nil , nil ))
numTokens += len ( tkm . Encode ( message . Role , nil , nil ))
numTokens += len ( tkm . Encode ( message . Name , nil , nil ))
if message . Name != "" {
numTokens += tokensPerName
}
}
numTokens += 3 // every reply is primed with <|start|>assistant<|message|>
return numTokens
}| Кодирование имени | Openai модели |
|---|---|
o200k_base | gpt-4o |
cl100k_base | gpt-4 , gpt-3.5-turbo , text-embedding-ada-002 , text-embedding-3-small , text-embedding-3-large |
p50k_base | Модели Codex, text-davinci-002 , text-davinci-003 |
r50k_base (или gpt2 ) | Модели GPT-3, такие как davinci |
| Название модели | Openai модели |
|---|---|
| GPT-4-* | O200K_BASE |
| GPT-4-* | CL100K_BASE |
| GPT-3,5-Turbo-* | CL100K_BASE |
| GPT-4O | O200K_BASE |
| GPT-4 | CL100K_BASE |
| GPT-3.5-Turbo | CL100K_BASE |
| Текст-давинка-003 | P50K_BASE |
| Текст-давинка-002 | P50K_BASE |
| Текст-давинка-001 | R50K_BASE |
| Text-Curie-001 | R50K_BASE |
| Текст-баббис-001 | R50K_BASE |
| Текст-Ада-001 | R50K_BASE |
| Давиньси | R50K_BASE |
| кюри | R50K_BASE |
| Бэббидж | R50K_BASE |
| ада | R50K_BASE |
| CODE-DAVINCI-002 | P50K_BASE |
| CODE-DAVINCI-001 | P50K_BASE |
| Code-Cushman-002 | P50K_BASE |
| Code-Cushman-001 | P50K_BASE |
| Davinci-Codex | P50K_BASE |
| Кушман-Кодекс | P50K_BASE |
| Text-Davinci-edit-001 | P50K_EDIT |
| Code-Davinci-edit-001 | P50K_EDIT |
| Текст-эмблдинг-ADA-002 | CL100K_BASE |
| Текст-эмбединг-3-ял | CL100K_BASE |
| Текст-эмблдинг-3-картанный | CL100K_BASE |
| Текст-симилар--давинка-001 | R50K_BASE |
| Текст-сайт-Curie-001 | R50K_BASE |
| Текст-симилар-баббидж-001 | R50K_BASE |
| Текст-симилар-Ада-001 | R50K_BASE |
| Текст-поиск--давинка-док-001 | R50K_BASE |
| Текст-поиск Curie-Doc-001 | R50K_BASE |
| Тексто-поиск-бэббейс-док-001 | R50K_BASE |
| Текстовый поиск-ада-DOC-001 | R50K_BASE |
| Кодовый-поиск-баббистский код-001 | R50K_BASE |
| кодовой-поиск-ада-код-001 | R50K_BASE |
| GPT2 | GPT2 |
Вы можете запустить тест в тестовой папке
результат
результат
Вы можете запустить эталон в тестовой папке
| имя | время/op | ОС | Процессор | текст | раз |
|---|---|---|---|---|---|
| Tiktoken-go | 8795ns | macOS 13.2 | Apple M1 | Udhr | 100000 |
| Тиктокен | 8838ns | macOS 13.2 | Apple M1 | Udhr | 100000 |
Похоже, спектакль почти такой же.
Возможно, разница связана с разницей в производительности машины.
Или, может быть, мой контрольный метод не подходит.
Если у вас есть лучший метод эталона или если вы хотите добавить свой контрольный результат, пожалуйста, не стесняйтесь отправить PR.
Для новой кодирования o200k_base он кажется медленнее, чем cl100k_base . Tiktoken-go немного медленнее, чем Tiktoken на следующем тесте.
| имя | кодирование | время/op | ОС | Процессор | текст | раз |
|---|---|---|---|---|---|---|
| Tiktoken-go | O200K_BASE | 108522 нс | Ubuntu 22.04 | Amd ryzen 9 5900hs | Udhr | 100000 |
| Тиктокен | O200K_BASE | 70198 нс | Ubuntu 22.04 | Amd ryzen 9 5900hs | Udhr | 100000 |
| Tiktoken-go | CL100K_BASE | 94502 нс | Ubuntu 22.04 | Amd ryzen 9 5900hs | Udhr | 100000 |
| Тиктокен | CL100K_BASE | 54642 нс | Ubuntu 22.04 | Amd ryzen 9 5900hs | Udhr | 100000 |
Грань