Repository navigation
Expand file tree
/
Copy pathpredictor_test.go
More file actions
115 lines (111 loc) · 3.63 KB
/
Copy pathpredictor_test.go
File metadata and controls
115 lines (111 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package layago
import (
"context"
"errors"
"github.com/UnicoLab/ul_layago/laya"
"github.com/UnicoLab/ul_layago/model"
"github.com/UnicoLab/ul_layago/tensor"
"math"
"reflect"
"strings"
"testing"
)
func TestCheckpointFacadePreservesNumericalParity(t *testing.T) {
p, err := Open(OpenOptions{Checkpoint: "testdata/parity/checkpoint", Workers: 1, Kernel: tensor.KernelGeneric})
if err != nil {
t.Fatal(err)
}
qs := []Question{{ID: "choice", Type: "choice", Instructions: "Pick the topic.", Options: []Option{{Key: "a"}, {Key: "b"}}}, {ID: "score", Type: "score", Instructions: "Score urgency.", Levels: []string{"low", "high"}}, {ID: "boolean", Type: "yes_no", Instructions: "Is this urgent?"}}
request := Request{State: "Hello", Questions: qs}
got, err := p.Predict(context.Background(), request)
if err != nil {
t.Fatal(err)
}
raw, err := laya.LoadCheckpoint("testdata/parity/checkpoint", laya.LoadOptions{})
if err != nil {
t.Fatal(err)
}
built := make([]laya.Question, len(qs))
for i, q := range qs {
built[i], err = p.question(q)
if err != nil {
t.Fatal(err)
}
}
expected, err := raw.Predict(context.Background(), request.State, built, model.Options{Parallel: tensor.Parallel{Workers: 1, Kernel: tensor.KernelGeneric}})
if err != nil {
t.Fatal(err)
}
for i, d := range got.Decisions {
if !reflect.DeepEqual(d.Probabilities, expected.Answers[i].Probs) {
t.Fatalf("numerical drift: %v != %v", d, expected.Answers[i])
}
if d.Decision != "escalate" || d.Truncated {
t.Fatalf("uncalibrated checkpoint decision: %v", d)
}
sum := 0.0
for _, v := range d.Probabilities {
sum += v
}
if math.Abs(sum-1) > 1e-9 {
t.Fatal(sum)
}
}
if got.Decisions[1].Type != "score" || got.Decisions[2].Type != "yes_no" || !got.RequiresDomainValidation {
t.Fatal(got)
}
}
func TestInputBudgetsAndCancellation(t *testing.T) {
p, err := Open(OpenOptions{Checkpoint: "testdata/parity/checkpoint", Workers: 1})
if err != nil {
t.Fatal(err)
}
q := Question{ID: "q", Type: "choice", Instructions: "Pick.", Options: []Option{{Key: "a"}, {Key: "b"}}}
r := Request{State: strings.Repeat("hello world ", 200), Questions: []Question{q}}
if _, err := p.Predict(context.Background(), r); !errors.Is(err, ErrTruncation) {
t.Fatalf("silent truncation: %v", err)
}
r.AllowTruncation = true
got, err := p.Predict(context.Background(), r)
if err != nil {
t.Fatal(err)
}
if !got.Decisions[0].Truncated || got.Decisions[0].Decision != "escalate" {
t.Fatal(got)
}
r.State = "Hi"
r.AllowTruncation = false
r.Questions[0].Options[0].Description = strings.Repeat("word ", 200)
if _, err := p.Predict(context.Background(), r); !errors.Is(err, ErrTruncation) {
t.Fatalf("option clipping: %v", err)
}
ctx, cancel := context.WithCancel(context.Background())
cancel()
if _, err := p.Predict(ctx, r); !errors.Is(err, context.Canceled) {
t.Fatal(err)
}
p.gate <- struct{}{}
if _, err := p.Predict(ctx, r); !errors.Is(err, context.Canceled) {
t.Fatal(err)
}
<-p.gate
}
func TestArtifactUsesPinnedOptions(t *testing.T) {
p, err := Open(OpenOptions{Artifact: "testdata/artifact/tiny-q/float32", Base: "testdata/parity/checkpoint", Workers: 1})
if err != nil {
t.Fatal(err)
}
q, err := p.question(Question{ID: "q", Task: "q_operation"})
if err != nil {
t.Fatal(err)
}
if len(q.Options) < 2 {
t.Fatal("trained options missing")
}
if _, err := p.question(Question{ID: "q", Task: "q_operation", Options: []Option{{Key: "wrong"}}}); err == nil {
t.Fatal("allowed incompatible options")
}
if _, err := p.question(Question{ID: "q", Task: "q_operation", Levels: []string{"wrong"}}); err == nil {
t.Fatal("allowed irrelevant levels")
}
}