Skip to content

Commit

Permalink
feat: show context token usage (j178#51)
Browse files Browse the repository at this point in the history
  • Loading branch information
j178 authored Apr 3, 2023
1 parent 115ac90 commit 9ddb13a
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 17 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/mattn/go-isatty v0.0.17
github.com/mitchellh/go-homedir v1.1.0
github.com/muesli/reflow v0.3.0
github.com/pkoukk/tiktoken-go v0.0.0-20230324104152-12d08d8436f6
github.com/postfinance/single v0.0.2
github.com/sashabaranov/go-openai v1.5.3
)
Expand All @@ -22,6 +23,7 @@ require (
github.com/aymerick/douceur v0.2.0 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/dlclark/regexp2 v1.8.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
Expand All @@ -39,5 +41,4 @@ require (
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
7 changes: 5 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.8.1 h1:6Lcdwya6GjPUNsBct8Lg/yRPwMhABj269AAzdGSiR+0=
github.com/dlclark/regexp2 v1.8.1/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
Expand Down Expand Up @@ -64,6 +66,8 @@ github.com/muesli/termenv v0.14.0 h1:8x9NFfOe8lmIWK4pgy3IfVEy47f+ppe3tUqdPZG2Uy0
github.com/muesli/termenv v0.14.0/go.mod h1:kG/pF1E7fh949Xhe156crRUrHNyK221IuGO7Ez60Uc8=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/pkoukk/tiktoken-go v0.0.0-20230324104152-12d08d8436f6 h1:yBoC9aDHaJn40P4us5RBXI1T3C7IxT+WPEJol5OZ0b4=
github.com/pkoukk/tiktoken-go v0.0.0-20230324104152-12d08d8436f6/go.mod h1:BijIqAP84FMYC4XbdJgjyMpiSjusU8x0Y0W9K2t0QtU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/postfinance/single v0.0.2 h1:YLjLxxeGDnsW93oK4CxxOFSVOOiBi1OyoK4ZTl5biJw=
Expand All @@ -77,8 +81,8 @@ github.com/sashabaranov/go-openai v1.5.3 h1:o6n6dj0h9u+5mE1m+D8eT0zYhh7229o8ymDd
github.com/sashabaranov/go-openai v1.5.3/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU=
Expand Down Expand Up @@ -108,4 +112,3 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
32 changes: 21 additions & 11 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,11 +388,12 @@ type QnA struct {
}

type Conversation struct {
manager *ConversationManager
Config ConversationConfig `json:"config"`
Forgotten []QnA `json:"forgotten,omitempty"`
Context []QnA `json:"context,omitempty"`
Pending *QnA `json:"pending,omitempty"`
manager *ConversationManager
contextTokens int
Config ConversationConfig `json:"config"`
Forgotten []QnA `json:"forgotten,omitempty"`
Context []QnA `json:"context,omitempty"`
Pending *QnA `json:"pending,omitempty"`
}

func (c *Conversation) AddQuestion(q string) {
Expand All @@ -406,6 +407,7 @@ func (c *Conversation) UpdatePending(ans string, done bool) {
c.Pending.Answer += ans
if done {
c.Context = append(c.Context, *c.Pending)
c.contextTokens = 0
if len(c.Context) > c.Config.ContextLength {
c.Forgotten = append(c.Forgotten, c.Context[0])
c.Context = c.Context[1:]
Expand Down Expand Up @@ -447,9 +449,17 @@ func (c *Conversation) GetContextMessages() []openai.ChatCompletionMessage {
return messages
}

func (c *Conversation) GetContextTokens() int {
if c.contextTokens == 0 {
c.contextTokens = tokenizer.CountMessagesTokens(c.Config.Model, c.GetContextMessages())
}
return c.contextTokens
}

func (c *Conversation) ForgetContext() {
c.Forgotten = append(c.Forgotten, c.Context...)
c.Context = nil
c.contextTokens = 0
}

func (c *Conversation) PendingAnswer() string {
Expand Down Expand Up @@ -935,16 +945,16 @@ func (m model) RenderFooter() string {
}

// token count
messages := m.conversations.Curr().GetContextMessages()
question := m.textarea.Value()
if len(messages) > 0 || len(question) > 0 {
messages = append(
messages, openai.ChatCompletionMessage{
if m.conversations.Curr().Len() > 0 || len(question) > 0 {
messages := []openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleUser,
Content: question,
},
)
tokens := tokenizer.CountMessagesTokens(m.conversations.Curr().Config.Model, messages)
}
tokens := m.conversations.Curr().GetContextTokens()
tokens += tokenizer.CountMessagesTokens(m.conversations.Curr().Config.Model, messages)
columns = append(columns, fmt.Sprintf("\U000F0C24 %d", tokens))
}

Expand Down
47 changes: 44 additions & 3 deletions tokenizer/tokenize.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,48 @@
package tokenizer

import "github.com/sashabaranov/go-openai"
import (
"github.com/pkoukk/tiktoken-go"
"github.com/sashabaranov/go-openai"
)

func CountMessagesTokens(engine string, messages []openai.ChatCompletionMessage) int {
return 127
var modelCache = map[string]*tiktoken.Tiktoken{}

func CountTokens(model, text string) int {
enc, ok := modelCache[model]
if !ok {
enc, _ = tiktoken.EncodingForModel(model)
modelCache[model] = enc
}
return len(enc.Encode(text, nil, nil))
}

// CountMessagesTokens based on https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb
func CountMessagesTokens(model string, messages []openai.ChatCompletionMessage) int {
var tokens int
var tokensPerMessage int
var tokensPerName int

switch model {
case openai.GPT3Dot5Turbo, openai.GPT3Dot5Turbo0301:
tokensPerMessage = 4 // every message follows <|start|>{role/name}\n{content}<|end|>\n
tokensPerName = -1 // if there's a name, the role is omitted
case openai.GPT4, openai.GPT40314, openai.GPT432K, openai.GPT432K0314:
tokensPerMessage = 3
tokensPerName = 1
}

for k := range messages {
tokens += tokensPerMessage

tokens += CountTokens(model, messages[k].Role)
tokens += CountTokens(model, messages[k].Content)
tokens += CountTokens(model, messages[k].Name)
if messages[k].Name != "" {
tokens += tokensPerName
}
}

tokens += 3 // every reply is primed with <|start|>assistant<|message|>

return tokens
}

0 comments on commit 9ddb13a

Please sign in to comment.