1
1
import PQueue from "p-queue" ;
2
+ import { Database , open } from "sqlite" ;
3
+ import sqlite3 from "sqlite3" ;
2
4
3
5
import { Dataset , ProblemId , Test } from "@app/lib/datasets" ;
4
- import { ChatCompletion , Model } from "@app/lib/models" ;
6
+ import { ChatCompletion , ChatQuery , hashQuery , Model } from "@app/lib/models" ;
5
7
6
- export const ValidAlgorithmTypes = [ "CoT" ] as const ;
8
+ export const ValidAlgorithmTypes = [ "CoT" , "CoT-consensus" ] as const ;
7
9
export type AlgorithmType = ( typeof ValidAlgorithmTypes ) [ number ] ;
8
10
9
11
export type TestResult = {
@@ -12,39 +14,108 @@ export type TestResult = {
12
14
check : boolean ;
13
15
} ;
14
16
15
- const CONCURRENCY = 4 ;
16
-
17
17
export abstract class Algorithm {
18
- abstract readonly algorithm : AlgorithmType ;
19
-
20
18
private history : {
21
19
createdAt : number ;
20
+ runId : string ;
22
21
test : ProblemId ;
22
+ queryHash : string ;
23
23
completion : ChatCompletion ;
24
24
check : boolean ;
25
25
} [ ] ;
26
26
27
- constructor ( ) {
27
+ private _sqlite : Database | null = null ;
28
+
29
+ protected dataset : Dataset ;
30
+ protected model : Model ;
31
+
32
+ constructor ( dataset : Dataset , model : Model ) {
28
33
this . history = [ ] ;
34
+ this . dataset = dataset ;
35
+ this . model = model ;
29
36
}
30
37
31
- storeCompletion ( {
38
+ abstract algorithm ( ) : AlgorithmType ;
39
+
40
+ async sqlite ( ) {
41
+ if ( this . _sqlite === null ) {
42
+ this . _sqlite = await open ( {
43
+ filename : `stores/${ this . runId ( ) } .sqlite` ,
44
+ driver : sqlite3 . Database ,
45
+ } ) ;
46
+ // this._sqlite = new Database(`stores/${this.runId()}.sqlite`);
47
+ const query =
48
+ "CREATE TABLE IF NOT EXISTS store (" +
49
+ "id BIGSERIAL PRIMARY KEY, " +
50
+ "created_at INTEGER NOT NULL, " +
51
+ "run_id TEXT NOT NULL, " +
52
+ "test TEXT NOT NULL, " +
53
+ "query_hash TEXT NOT NULL, " +
54
+ "completion TEXT NOT NULL, " +
55
+ "is_check INTEGER NOT NULL" +
56
+ ")" ;
57
+ await this . _sqlite . exec ( query ) ;
58
+ }
59
+ return this . _sqlite ;
60
+ }
61
+
62
+ runId ( ) : string {
63
+ return `${ this . model . provider } -${ this . model . model ( ) } -${
64
+ this . dataset . dataset
65
+ } -${ this . algorithm ( ) } `;
66
+ }
67
+
68
+ async storeCompletion ( {
32
69
test,
70
+ query,
33
71
completion,
34
72
check,
35
73
} : {
36
74
test : Test ;
37
- check : boolean ;
75
+ query : ChatQuery ;
38
76
completion : ChatCompletion ;
39
- } ) : void {
77
+ check : boolean ;
78
+ } ) {
79
+ const db = await this . sqlite ( ) ;
80
+
81
+ const now = Date . now ( ) ;
82
+
83
+ await db . run (
84
+ "INSERT INTO store (created_at, run_id, test, query_hash, completion, is_check) VALUES (?, ?, ?, ?, ?, ?)" ,
85
+ [
86
+ now ,
87
+ this . runId ( ) ,
88
+ test . id ,
89
+ hashQuery ( query ) ,
90
+ JSON . stringify ( completion ) ,
91
+ check ? 1 : 0 ,
92
+ ]
93
+ ) ;
94
+
40
95
this . history . push ( {
41
- createdAt : Date . now ( ) ,
96
+ createdAt : now ,
97
+ runId : this . runId ( ) ,
42
98
test : test . id ,
99
+ queryHash : hashQuery ( query ) ,
43
100
completion,
44
101
check,
45
102
} ) ;
46
103
}
47
104
105
+ async runCompletion ( query : ChatQuery ) : Promise < ChatCompletion > {
106
+ const db = await this . sqlite ( ) ;
107
+
108
+ const result = await db . get (
109
+ "SELECT * FROM store WHERE run_id = ? AND query_hash = ?" ,
110
+ [ this . runId ( ) , hashQuery ( query ) ]
111
+ ) ;
112
+ if ( result ) {
113
+ return JSON . parse ( result . completion ) ;
114
+ }
115
+
116
+ return await this . model . completionWithRetry ( query ) ;
117
+ }
118
+
48
119
stats ( ) {
49
120
const now = Date . now ( ) ;
50
121
const window = this . history . filter ( ( x ) => x . createdAt > now - 60000 ) ;
@@ -83,38 +154,60 @@ export abstract class Algorithm {
83
154
) ;
84
155
}
85
156
157
+ finalStats ( ) {
158
+ if ( this . history . length > 1 ) {
159
+ const first = this . history [ 0 ] ;
160
+ const last = this . history [ this . history . length - 1 ] ;
161
+ const duration = last . createdAt - first . createdAt ;
162
+ const rate = this . history . length / ( duration / 1000 ) ;
163
+ const completionTokensTotal = this . history . reduce (
164
+ ( acc , x ) => acc + x . completion . usage . completionTokens ,
165
+ 0
166
+ ) ;
167
+ const promptTokensTotal = this . history . reduce (
168
+ ( acc , x ) => acc + x . completion . usage . promptTokens ,
169
+ 0
170
+ ) ;
171
+ const completionTokensRate = completionTokensTotal / ( duration / 1000 ) ;
172
+ const promptTokensRate = promptTokensTotal / ( duration / 1000 ) ;
173
+
174
+ console . log (
175
+ `Final stats: ` +
176
+ `rate=${ rate . toFixed ( 2 ) } /s` +
177
+ `promptTokensRate=${ promptTokensRate . toFixed ( 3 ) } /s ` +
178
+ `completionTokensRate=${ completionTokensRate . toFixed ( 2 ) } /s ` +
179
+ `promptTokensTotal=${ promptTokensTotal } ` +
180
+ `completionTokensTotal=${ completionTokensTotal } `
181
+ ) ;
182
+ }
183
+ }
184
+
86
185
abstract runOne ( {
87
- model,
88
- dataset,
89
186
test,
90
187
debug,
188
+ iteration,
91
189
} : {
92
- model : Model ;
93
- dataset : Dataset ;
94
190
test : Test ;
95
191
debug ?: boolean ;
192
+ iteration ?: number ;
96
193
} ) : Promise < TestResult > ;
97
194
98
195
async run ( {
99
- model,
100
- dataset,
101
196
tests,
197
+ concurrency,
102
198
debug,
103
199
} : {
104
- model : Model ;
105
- dataset : Dataset ;
106
200
tests : Test [ ] ;
201
+ concurrency : number ;
107
202
debug ?: boolean ;
108
203
} ) : Promise < TestResult [ ] > {
109
204
const queue = new PQueue ( {
110
- concurrency : CONCURRENCY ,
205
+ concurrency,
111
206
} ) ;
112
207
113
208
const results = (
114
209
await Promise . all (
115
- tests . map ( ( test ) =>
116
- queue . add ( ( ) => this . runOne ( { model, dataset, test, debug } ) )
117
- )
210
+ tests . map ( ( test ) => queue . add ( ( ) => this . runOne ( { test, debug } ) ) )
118
211
)
119
212
) . filter ( ( x ) => x ) ;
120
213
@@ -124,4 +217,6 @@ export abstract class Algorithm {
124
217
125
218
return results as TestResult [ ] ;
126
219
}
220
+
221
+ abstract computeResults ( ) : void ;
127
222
}
0 commit comments