@@ -4,19 +4,16 @@ package datasets
44
55import (
66 "bufio"
7- "encoding/json"
87 "errors"
98 "fmt"
109 "io"
11- "path/filepath"
1210 "slices"
1311
1412 "github.com/gomlx/gomlx/ml/train"
1513 "github.com/gomlx/gomlx/types/tensors"
1614
1715 "github.com/knights-analytics/hugot/pipelineBackends"
1816 "github.com/knights-analytics/hugot/pipelines"
19- "github.com/knights-analytics/hugot/util"
2017)
2118
2219type Dataset interface {
@@ -41,154 +38,6 @@ type SemanticSimilarityDataset struct {
4138 verbose bool
4239}
4340
44- func (s * SemanticSimilarityDataset ) SetVerbose (v bool ) {
45- s .verbose = v
46- }
47-
48- func (s * SemanticSimilarityDataset ) SetTokenizationPipeline (pipeline pipelineBackends.Pipeline ) error {
49- if pipeline == nil {
50- return fmt .Errorf ("pipeline is required" )
51- }
52- if _ , ok := pipeline .(* pipelines.FeatureExtractionPipeline ); ! ok {
53- return fmt .Errorf ("tokenization pipeline must be a FeatureExtractionPipeline" )
54- }
55- s .pipeline = pipeline .(* pipelines.FeatureExtractionPipeline )
56- return nil
57- }
58-
59- func (s * SemanticSimilarityDataset ) Validate () error {
60- if len (s .trainingExamples ) == 0 {
61- if s .trainingPath == "" {
62- return fmt .Errorf ("training path is required" )
63- }
64- if filepath .Ext (s .trainingPath ) != ".jsonl" {
65- return fmt .Errorf ("training path must be a .jsonl file" )
66- }
67- }
68- return nil
69- }
70-
71- // SemanticSimilarityExample is a single example for the semantic similarity dataset.
72- type SemanticSimilarityExample struct {
73- Sentence1 string `json:"sentence1"`
74- Sentence2 string `json:"sentence2"`
75- Score float32 `json:"score"`
76- Data map [string ]any // to store any additional data for the example. Not used by the dataset.
77- }
78-
79- type ExamplePreprocessFunc func ([]SemanticSimilarityExample ) ([]SemanticSimilarityExample , error )
80-
81- // NewSemanticSimilarityDataset creates a new SemanticSimilarityDataset.
82- // The trainingPath must be a .jsonl file where each line has the following format:
83- // {"sentence1":"A plane is taking off.","sentence2":"An air plane is taking off.","score":1.0}
84- // The score is a float value between 0 and 1.
85- // preprocessFunc here must be a function that takes a slice of SemanticSimilarityExample and returns a slice of SemanticSimilarityExample.
86- // This function can be used to apply any custom preprocessing to the example batch before they are passed to the model.
87- func NewSemanticSimilarityDataset (trainingPath string , batchSize int , preprocessFunc ExamplePreprocessFunc ) (* SemanticSimilarityDataset , error ) {
88- d := & SemanticSimilarityDataset {
89- trainingPath : trainingPath ,
90- batchSize : batchSize ,
91- preprocessFunc : preprocessFunc ,
92- }
93- if err := d .Validate (); err != nil {
94- return nil , err
95- }
96-
97- sourceReadCloser , err := util .OpenFile (trainingPath )
98- if err != nil {
99- return nil , err
100- }
101- d .reader = bufio .NewReader (sourceReadCloser )
102- d .sourceFile = sourceReadCloser
103- return d , nil
104- }
105-
106- // NewInMemorySemanticSimilarityDataset creates a new SemanticSimilarityDataset in memory from a slice of examples.
107- // preprocessFunc here must be a function that takes a slice of SemanticSimilarityExample and returns a slice of SemanticSimilarityExample.
108- // This function can be used to apply any custom preprocessing to the example batch before they are passed to the model.
109- func NewInMemorySemanticSimilarityDataset (examples []SemanticSimilarityExample , batchSize int , preprocessFunc ExamplePreprocessFunc ) (* SemanticSimilarityDataset , error ) {
110- d := & SemanticSimilarityDataset {
111- trainingExamples : examples ,
112- batchSize : batchSize ,
113- preprocessFunc : preprocessFunc ,
114- }
115- if err := d .Validate (); err != nil {
116- return nil , err
117- }
118- return d , nil
119- }
120-
121- // Reset resets the dataset to the beginning of the training data (after the epoch is done).
122- func (s * SemanticSimilarityDataset ) Reset () {
123- if s .verbose {
124- fmt .Printf ("completed epoch in %d batches of %d examples, resetting dataset\n " , s .batchN , s .batchSize )
125- }
126- s .batchN = 0
127-
128- if len (s .trainingExamples ) == 0 {
129- if err := s .sourceFile .Close (); err != nil {
130- panic (err )
131- }
132-
133- sourceReadCloser , err := util .OpenFile (s .trainingPath )
134- if err != nil {
135- panic (err ) // note: these panics will be catched later with the TryExcept
136- }
137- s .sourceFile = sourceReadCloser
138-
139- // restart the reader
140- s .reader = bufio .NewReader (sourceReadCloser )
141- }
142- }
143-
144- // YieldRaw returns the next raw batch of examples from the dataset. Note that if a preprocessing function has been
145- // provided at creation time, the examples will be preprocessed before being returned.
146- func (s * SemanticSimilarityDataset ) YieldRaw () ([]SemanticSimilarityExample , error ) {
147- batchCounter := 0
148-
149- var lineBytes []byte
150- var readErr error
151- var lineData SemanticSimilarityExample
152-
153- examplesBatch := make ([]SemanticSimilarityExample , 0 , s .batchSize )
154- var preprocessErr error
155-
156- for batchCounter < s .batchSize {
157- if len (s .trainingExamples ) > 0 {
158- // in memory dataset
159- start := s .batchN * s .batchSize
160- if start >= len (s .trainingExamples ) {
161- return examplesBatch , io .EOF // return error for reset
162- }
163- end := start + s .batchSize
164- for i := start ; i < end && i < len (s .trainingExamples ); i ++ {
165- examplesBatch = append (examplesBatch , s .trainingExamples [i ])
166- }
167- } else {
168- lineBytes , readErr = util .ReadLine (s .reader )
169- if readErr != nil {
170- return examplesBatch , readErr
171- }
172-
173- if err := json .Unmarshal (lineBytes , & lineData ); err != nil {
174- return nil , fmt .Errorf ("failed to parse JSON line: %w" , err )
175- }
176- examplesBatch = append (examplesBatch , lineData )
177- }
178- batchCounter ++
179- }
180- s .batchN ++
181-
182- if s .preprocessFunc != nil {
183- examplesBatch , preprocessErr = s .preprocessFunc (examplesBatch )
184- if preprocessErr != nil {
185- return nil , preprocessErr
186- }
187- }
188-
189- return examplesBatch , nil
190- }
191-
19241// Yield returns the next batch of examples from the dataset. The examples are tokenized and converted to tensors for the training process.
19342func (s * SemanticSimilarityDataset ) Yield () (spec any , inputs []* tensors.Tensor , labels []* tensors.Tensor , err error ) {
19443 exampleBatch , rawErr := s .YieldRaw ()
@@ -233,10 +82,3 @@ func (s *SemanticSimilarityDataset) Yield() (spec any, inputs []*tensors.Tensor,
23382
23483 return nil , slices .Concat (inputLhs , inputRhs ), labelTensor , rawErr
23584}
236-
237- func (s * SemanticSimilarityDataset ) Close () error {
238- if s .sourceFile != nil {
239- return s .sourceFile .Close ()
240- }
241- return nil
242- }
0 commit comments