-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcrossencoder.go
More file actions
97 lines (83 loc) · 2.4 KB
/
Copy pathcrossencoder.go
File metadata and controls
97 lines (83 loc) · 2.4 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
package rocketqa
import (
"fmt"
"github.com/go-aie/paddle"
"github.com/go-aie/rocketqa/internal"
)
type CrossEncoderConfig struct {
ModelPath, ParamsPath string
VocabFile string
DoLowerCase bool
MaxSeqLength int
ForCN bool
// The maximum number of predictors for concurrent inferences.
// Defaults to the value of runtime.NumCPU.
MaxConcurrency int
}
type CrossEncoder struct {
engine *paddle.Engine
generator *internal.Generator
}
func NewCrossEncoder(cfg *CrossEncoderConfig) (*CrossEncoder, error) {
generator, err := internal.NewGenerator(internal.GeneratorConfig{
VocabFile: cfg.VocabFile,
DoLowerCase: cfg.DoLowerCase,
MaxSeqLength: cfg.MaxSeqLength,
ForCN: cfg.ForCN,
})
if err != nil {
return nil, err
}
return &CrossEncoder{
engine: paddle.NewEngine(cfg.ModelPath, cfg.ParamsPath, cfg.MaxConcurrency),
generator: generator,
}, nil
}
func (ce *CrossEncoder) Rank(queries, paras, titles []string) ([]float32, error) {
n := len(queries)
if n == 0 {
return nil, nil
}
if len(paras) != n {
return nil, fmt.Errorf("len(paras) does not equal len(queries)")
}
if len(titles) > 0 && len(titles) != n {
return nil, fmt.Errorf("len(titles) does not equal len(queries)")
}
var records []internal.Record
for i := 0; i < n; i++ {
e := &internal.Example{
Query: queries[i],
Para: paras[i],
}
if len(titles) > 0 {
e.Title = titles[i]
}
records = append(records, ce.generator.GenerateCE(e))
}
inputs := ce.getInputs(records)
outputs := ce.engine.Infer(inputs)
// We only care the first (also the only one) output.
result := outputs[0]
// Extract the second column (Assume that joint_training == 0)
return paddle.NewMatrix[float32](result).Col(1), nil
}
func (ce *CrossEncoder) getInputs(records []internal.Record) []paddle.Tensor {
var tokenIDs [][]int64
var textTypeIDs [][]int64
var positionIDs [][]int64
for _, r := range records {
tokenIDs = append(tokenIDs, r.TokenIDs)
textTypeIDs = append(textTypeIDs, r.TextTypeIDs)
positionIDs = append(positionIDs, r.PositionIDs)
}
tokenIDs, inputMasks := ce.generator.Pad(tokenIDs)
textTypeIDs, _ = ce.generator.Pad(textTypeIDs)
positionIDs, _ = ce.generator.Pad(positionIDs)
return []paddle.Tensor{
paddle.NewInputTensor(tokenIDs),
paddle.NewInputTensor(textTypeIDs),
paddle.NewInputTensor(positionIDs),
paddle.NewInputTensor(inputMasks),
}
}