package main import ( "fmt" "log" "math" "go.jknobloc.com/x/llm" ) type pplResult struct { v float64 n int } func perplexity() { d := data() m := model() t := tokenizer() e := llm.NewEvaluator(m, t, func(job llm.Job, logProbs []float32, tokens []int) pplResult { total := float64(0) n := 0 for _, p := range logProbs { total -= float64(p) n++ } return pplResult{ v: total, n: n, } }, llm.EvaluatorConfig{ BatchSize: 1, NumWorkers: 4, }) total := float64(0) n := 0 cfg := llm.TokenBufferConfig{ Window: 1024, Stride: 512, PadLeft: false, // probably not fine since we don't adjust model inputs for padding PadRight: true, // fine since we remove padded log probs anyway PadTokenID: 50256, } if err := e.RunAndCollect("Perplexity", d, cfg, func(r pplResult) error { total += r.v n += r.n return nil }); err != nil { log.Fatal(err) } avg := total / float64(n) ppl := math.Exp(avg) fmt.Println(ppl) fmt.Printf("%d tokens\n", n) if err := m.Destroy(); err != nil { log.Fatal(err) } }