简体中文
Tiktoken d'Openai en go.
Tiktoken est un tokeniser BPE rapide à utiliser avec les modèles d'Openai.
Ceci est un port du tiktoken d'origine.
go get github.com/pkoukk/tiktoken-goTiktoken-Go a le même mécanisme de cache que la bibliothèque Tiktoken d'origine.
Vous pouvez définir le répertoire de cache en utilisant la variable d'environnement tiktoken_cache_dir.
Une fois cette variable définie, TikToken-Go utilisera ce répertoire pour mettre en cache le dictionnaire de jeton.
Si vous ne définissez pas cette variable d'environnement, TikToken-Go téléchargera le dictionnaire chaque fois que vous initialisez un encodage pour la première fois.
Si vous ne souhaitez pas utiliser de cache ou télécharger le dictionnaire à chaque fois, vous pouvez utiliser un chargeur BPE alternatif.
Appelez simplement tiktoken.SetBpeLoader avant d'appeler tiktoken.GetEncoding ou tiktoken.EncodingForModel .
BpeLoader est une interface, vous pouvez implémenter votre propre chargeur BPE en implémentant cette interface.
Le chargeur BPE hors ligne charge le dictionnaire BPE à partir de fichiers ENCHED, il est utile si vous ne souhaitez pas télécharger le dictionnaire au moment de l'exécution.
En raison de la taille du dictionnaire BPE, ce chargeur est dans un autre projet.
Inclure si vous avez besoin de ce chargeur: 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 ))
}Vous trouverez ci-dessous un exemple de fonction pour compter les jetons pour les messages transmis à GPT-3.5-Turbo ou GPT-4.
Le code suivant a été écrit sur la base d'exemples Openai-Cookbook au Wednesday, 28 June 2023 .
Veuillez noter que la méthode de calcul du jeton pour le message peut changer à tout moment, donc ce code ne peut pas nécessairement être applicable à l'avenir.
Si vous avez besoin d'un calcul précis, veuillez vous référer à la documentation officielle.
Si vous constatez que ce code n'est plus applicable, n'hésitez pas à soumettre un PR ou un problème.
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
}| Nom de codage | Modèles 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 | Modèles Codex, text-davinci-002 , text-davinci-003 |
r50k_base (ou gpt2 ) | Des modèles GPT-3 comme davinci |
| Nom du modèle | Modèles Openai |
|---|---|
| gpt-4o- * | 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 |
| text-davinci-003 | P50K_BASE |
| text-davinci-002 | P50K_BASE |
| text-davinci-001 | R50K_BASE |
| Text-Curie-001 | R50K_BASE |
| Text-Babbage-001 | R50K_BASE |
| Text-ADA-001 | R50K_BASE |
| daVinci | R50K_BASE |
| curie | R50K_BASE |
| babbage | R50K_BASE |
| Ada | 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 |
| codémex | P50K_BASE |
| text-davinci-edit-001 | p50k_edit |
| code-davinci-edit-001 | p50k_edit |
| Texte-embelli-ADA-002 | CL100K_BASE |
| Texte-incliné-3-Small | CL100K_BASE |
| texton | CL100K_BASE |
| Texte-similitude-Davinci-001 | R50K_BASE |
| Texte-similicité-Curie-001 | R50K_BASE |
| Text-Similarity-Babbage-001 | R50K_BASE |
| Texte-similitude-ADA-001 | R50K_BASE |
| text-search-davinci-doc-001 | R50K_BASE |
| Text-Search-Curie-doc-001 | R50K_BASE |
| Text-Search-Babbage-doc-001 | R50K_BASE |
| text-search-ated-doc-001 | R50K_BASE |
| Code-Search-Babbage-Code-001 | R50K_BASE |
| Code-Search-Ada-Code-001 | R50K_BASE |
| gpt2 | gpt2 |
vous pouvez exécuter le test dans le dossier de test
résultat
résultat
Vous pouvez exécuter Benchmark dans le dossier de test
| nom | Temps / OP | OS | processeur | texte | fois |
|---|---|---|---|---|---|
| tiktoken-go | 8795ns | macOS 13.2 | Apple M1 | Udhr | 100000 |
| tiktoken | 8838ns | macOS 13.2 | Apple M1 | Udhr | 100000 |
Il semble que la performance soit presque la même.
Peut-être que la différence est due à la différence dans les performances de la machine.
Ou peut-être que ma méthode de référence n'est pas appropriée.
Si vous avez une meilleure méthode de référence ou si vous souhaitez ajouter votre résultat de référence, n'hésitez pas à soumettre un PR.
Pour un nouveau codage o200k_base , il semble plus lent que cl100k_base . Tiktoken-Go est légèrement plus lent que Tiktoken sur la référence suivante.
| nom | codage | Temps / OP | OS | processeur | texte | fois |
|---|---|---|---|---|---|---|
| tiktoken-go | O200K_BASE | 108522 ns | Ubuntu 22.04 | AMD Ryzen 9 5900HS | Udhr | 100000 |
| tiktoken | O200K_BASE | 70198 ns | Ubuntu 22.04 | AMD Ryzen 9 5900HS | Udhr | 100000 |
| tiktoken-go | CL100K_BASE | 94502 ns | Ubuntu 22.04 | AMD Ryzen 9 5900HS | Udhr | 100000 |
| tiktoken | CL100K_BASE | 54642 ns | Ubuntu 22.04 | AMD Ryzen 9 5900HS | Udhr | 100000 |
Mit