textopt 0.0.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -25
- package/dist/bootstrap-search/index.cjs +159 -73
- package/dist/bootstrap-search/index.d.cts +32 -10
- package/dist/bootstrap-search/index.d.mts +32 -10
- package/dist/bootstrap-search/index.mjs +150 -66
- package/dist/demos-9v5ts7F3.cjs +244 -0
- package/dist/{demos-B0pVQjYC.d.mts → demos-ASsSXYXA.d.mts} +10 -3
- package/dist/demos-Brobjfuc.mjs +215 -0
- package/dist/{demos-BTuzFNsp.d.cts → demos-ByaLZy-Z.d.cts} +10 -3
- package/dist/file-cache.cjs +27 -8
- package/dist/file-cache.d.cts +13 -0
- package/dist/file-cache.d.mts +13 -0
- package/dist/file-cache.mjs +27 -8
- package/dist/gepa/index.cjs +128 -80
- package/dist/gepa/index.d.cts +15 -7
- package/dist/gepa/index.d.mts +15 -7
- package/dist/gepa/index.mjs +101 -55
- package/dist/index.cjs +157 -30
- package/dist/index.d.cts +177 -7
- package/dist/index.d.mts +177 -7
- package/dist/index.mjs +139 -18
- package/dist/{math-COOofUyv.cjs → math-BhlziRPc.cjs} +60 -9
- package/dist/math-Dqme4rYz.mjs +123 -0
- package/dist/mipro/index.cjs +104 -70
- package/dist/mipro/index.d.cts +17 -14
- package/dist/mipro/index.d.mts +17 -14
- package/dist/mipro/index.mjs +90 -58
- package/dist/opro/index.cjs +136 -51
- package/dist/opro/index.d.cts +17 -9
- package/dist/opro/index.d.mts +17 -9
- package/dist/opro/index.mjs +121 -38
- package/dist/{optimizer-B7SpRwl7.d.cts → optimizer-4Zv-Zt2t.d.cts} +90 -5
- package/dist/{optimizer-DqCoth_w.d.mts → optimizer-Ds5mzYjz.d.mts} +90 -5
- package/dist/random-search/index.cjs +99 -49
- package/dist/random-search/index.d.cts +15 -13
- package/dist/random-search/index.d.mts +15 -13
- package/dist/random-search/index.mjs +89 -41
- package/dist/{reflection-Cr_upzU0.d.mts → reflection-CMezGu6u.d.mts} +38 -14
- package/dist/{reflection-CQToe-5B.d.cts → reflection-D0A7eahD.d.cts} +38 -14
- package/dist/reporting-bq007_2z.d.cts +294 -0
- package/dist/reporting-bq007_2z.d.mts +294 -0
- package/dist/simba/index.cjs +216 -83
- package/dist/simba/index.d.cts +53 -13
- package/dist/simba/index.d.mts +53 -13
- package/dist/simba/index.mjs +206 -75
- package/dist/testing.cjs +1 -0
- package/dist/testing.d.cts +5 -3
- package/dist/testing.d.mts +5 -3
- package/dist/testing.mjs +1 -1
- package/dist/{evaluation-OZOp6TB7.cjs → warnings-CWRJF-jA.cjs} +228 -5
- package/dist/{evaluation-BV0nSZVx.mjs → warnings-OxvDi9kN.mjs} +175 -6
- package/docs/adapters.md +169 -0
- package/docs/benchmark.md +90 -0
- package/docs/data-prep.md +113 -0
- package/docs/distillation.md +128 -0
- package/docs/evaluation.md +87 -0
- package/docs/metric-preflight.md +132 -0
- package/docs/optimizers.md +293 -0
- package/docs/tuning.md +130 -0
- package/package.json +6 -4
- package/dist/demos-B9BJiNKz.cjs +0 -143
- package/dist/demos-Degx6UmP.mjs +0 -126
- package/dist/math-DhrDmpFS.mjs +0 -78
- package/dist/types-CWv4IQFF.d.cts +0 -129
- package/dist/types-CWv4IQFF.d.mts +0 -129
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { C as componentNames, S as UsageTotals, _ as EvaluationPhase, a as RunFinished, b as ScoreResult, c as RunWarning, d as seedScoreWarnings, f as Adapter, g as EvaluationContext, h as EvaluationBatch, i as Reporter, l as RunWarningCode, m as EvaluateArgs, n as OptimizerEvent, o as isCandidateAccepted, p as Candidate, r as ReportableEvent, s as isRunFinished, t as CandidateAccepted, u as resolveValidationSet, v as EvaluationSplit, x as TextModel, y as RolloutUsage } from "./reporting-bq007_2z.cjs";
|
|
2
2
|
import { n as EvaluationCache, r as createMemoryCache, t as CachedScore } from "./cache-CuSo0NJ8.cjs";
|
|
3
3
|
import { t as Rng } from "./rng-BR5MOedA.cjs";
|
|
4
|
-
import { a as
|
|
5
|
-
import { a as EvaluateBatchArgs, c as Evaluator, d as costExhausted, f as createEvaluator, g as createBudget, h as Budget, i as BudgetExhausted, l as RetryPolicy, m as requireMeasuredMean, n as OptimizerResult, o as EvaluateTracedArgs, p as measuredMean, r as OptimizerTask, s as EvaluationEvent, t as Optimizer, u as ScoredBatch } from "./optimizer-
|
|
4
|
+
import { a as harvestFewShotExamples, i as formatDemos, n as Demo, o as parseDemos, r as DemoRenderer, t as BootstrapResult } from "./demos-ByaLZy-Z.cjs";
|
|
5
|
+
import { a as EvaluateBatchArgs, c as Evaluator, d as costExhausted, f as createEvaluator, g as createBudget, h as Budget, i as BudgetExhausted, l as RetryPolicy, m as requireMeasuredMean, n as OptimizerResult, o as EvaluateTracedArgs, p as measuredMean, r as OptimizerTask, s as EvaluationEvent, t as Optimizer, u as ScoredBatch } from "./optimizer-4Zv-Zt2t.cjs";
|
|
6
6
|
import { t as BatchSampler } from "./sampling-axOwfZf5.cjs";
|
|
7
7
|
//#region src/checkpoint.d.ts
|
|
8
8
|
/**
|
|
@@ -46,6 +46,10 @@ interface ComparisonRun {
|
|
|
46
46
|
bestScore: number;
|
|
47
47
|
testScore?: number;
|
|
48
48
|
metricCalls: number;
|
|
49
|
+
/** Rollouts this run got from the cache instead of paying for. */
|
|
50
|
+
cacheHits: number;
|
|
51
|
+
/** Calls to a proposal or reflection model, outside the metric budget. */
|
|
52
|
+
reflectionCalls: number;
|
|
49
53
|
costUsd: number;
|
|
50
54
|
stopReason: string;
|
|
51
55
|
}
|
|
@@ -58,12 +62,33 @@ interface ComparisonSummary {
|
|
|
58
62
|
maxScore: number;
|
|
59
63
|
meanMetricCalls: number;
|
|
60
64
|
meanCostUsd: number;
|
|
65
|
+
meanCacheHits: number;
|
|
66
|
+
meanReflectionCalls: number;
|
|
67
|
+
/**
|
|
68
|
+
* How many distinct values this entrant's score took across its seeds.
|
|
69
|
+
* 1 means every seed landed on the same number — the seed changed nothing
|
|
70
|
+
* about the outcome, whatever the search did internally with it.
|
|
71
|
+
*/
|
|
72
|
+
distinctScores: number;
|
|
61
73
|
/**
|
|
62
74
|
* How often the winner's margin over this entrant would arise if the two
|
|
63
|
-
* were equally good and each seed's outcome were a coin flip. Absent for
|
|
64
|
-
* winner itself
|
|
75
|
+
* were equally good and each seed's outcome were a coin flip. Absent for
|
|
76
|
+
* the winner itself, and also absent when every seed produced the exact
|
|
77
|
+
* same margin: a sign-flip test over n seeds is answering a question about
|
|
78
|
+
* n independent trials, and identical margins mean the seed never actually
|
|
79
|
+
* put that to the test — there was one realization, repeated. Reporting a
|
|
80
|
+
* p-value there would state a precision (as fine as 2^-n) that the run
|
|
81
|
+
* never earned, so it is withheld rather than printed misleadingly small.
|
|
65
82
|
*/
|
|
66
83
|
pValueVsWinner?: number;
|
|
84
|
+
/**
|
|
85
|
+
* `pValueVsWinner` after Holm-Bonferroni step-down across the other
|
|
86
|
+
* entrants in this same `compare()` call — the family the raw p-value
|
|
87
|
+
* would otherwise be read against in isolation. Absent wherever the raw
|
|
88
|
+
* p-value is: a withheld comparison has nothing to adjust, but it still
|
|
89
|
+
* occupies a slot in the family the other comparisons are corrected for.
|
|
90
|
+
*/
|
|
91
|
+
pValueVsWinnerHolm?: number;
|
|
67
92
|
}
|
|
68
93
|
interface Comparison {
|
|
69
94
|
/** Highest mean score. Read `pValueVsWinner` before believing it. */
|
|
@@ -85,7 +110,7 @@ interface Comparison {
|
|
|
85
110
|
* seed is constructor config and every optimizer here is deterministic given
|
|
86
111
|
* one — comparing two entrants at a single seed compares two anecdotes. It also
|
|
87
112
|
* leaves the task where the caller builds it, which is the only place the
|
|
88
|
-
* optimizer-specific parts of it (`reflect`, `cache`, `
|
|
113
|
+
* optimizer-specific parts of it (`reflect`, `cache`, `reporters`) are known.
|
|
89
114
|
*/
|
|
90
115
|
declare function compare<K extends string, Output = unknown>(args: {
|
|
91
116
|
entrants: Record<string, (args: {
|
|
@@ -136,11 +161,156 @@ declare function createDeadline(args: {
|
|
|
136
161
|
now?: () => number;
|
|
137
162
|
}): Deadline;
|
|
138
163
|
//#endregion
|
|
164
|
+
//#region src/harvest.d.ts
|
|
165
|
+
/**
|
|
166
|
+
* One rollout worth keeping: what went in, what the system produced, and how
|
|
167
|
+
* that output scored. Harvested, never written — the value of the pair is that
|
|
168
|
+
* the system actually produced the output and the metric actually rewarded it.
|
|
169
|
+
*/
|
|
170
|
+
interface Rollout<Datum = unknown, Output = unknown> {
|
|
171
|
+
input: Datum;
|
|
172
|
+
output: Output;
|
|
173
|
+
score: number;
|
|
174
|
+
}
|
|
175
|
+
interface HarvestResult<Datum, Output> {
|
|
176
|
+
rollouts: Rollout<Datum, Output>[];
|
|
177
|
+
/** Rollouts this cost. Harvesting is cheap, not free. */
|
|
178
|
+
metricCalls: number;
|
|
179
|
+
/**
|
|
180
|
+
* Tokens and dollars this cost. Harvesting runs on its own evaluator, so a
|
|
181
|
+
* caller that bounds spend has to fold these into its own totals.
|
|
182
|
+
*/
|
|
183
|
+
usage: UsageTotals;
|
|
184
|
+
/** Instances run, including the ones the metric did not reward. */
|
|
185
|
+
attempted: number;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Run a candidate over data and keep the rollouts the metric rewarded.
|
|
189
|
+
*
|
|
190
|
+
* The library's one paid collection primitive, with two consumers: a few-shot
|
|
191
|
+
* block wants four of these, and a distillation set wants thousands. Both are
|
|
192
|
+
* the same pass — run the candidate, score it, keep what cleared the bar — so
|
|
193
|
+
* both share the budget, retry and transient-failure handling that pass needs.
|
|
194
|
+
*
|
|
195
|
+
* Which data to sweep is the caller's decision and the consequential one. A
|
|
196
|
+
* validation set is the wrong choice: it is the set that selected the candidate,
|
|
197
|
+
* so the rollouts it yields are enriched for the candidate's fit to those
|
|
198
|
+
* instances rather than to the task. Prefer the training set, or a pool held
|
|
199
|
+
* out of the run entirely.
|
|
200
|
+
*/
|
|
201
|
+
declare function harvestRollouts<Datum, Trajectory, Output, K extends string = string>(args: {
|
|
202
|
+
adapter: Adapter<Datum, Trajectory, Output, K>;
|
|
203
|
+
/** The candidate to run. Usually a run's winner, sometimes the seed. */
|
|
204
|
+
candidate: Candidate<K>;
|
|
205
|
+
data: readonly Datum[];
|
|
206
|
+
/**
|
|
207
|
+
* Score a rollout must reach to be kept. Unset keeps every rollout the
|
|
208
|
+
* metric rewarded at all, which is what MIPROv2's bootstrapper does without
|
|
209
|
+
* a `metric_threshold`: it keeps a trace on any truthy score and only
|
|
210
|
+
* compares against a number once one is configured.
|
|
211
|
+
*
|
|
212
|
+
* Demanding a perfect score instead is the right call for a boolean metric
|
|
213
|
+
* and the wrong one for a graded metric, where it throws away every rollout
|
|
214
|
+
* that was most of the way there — which on a hard task is all of them.
|
|
215
|
+
*/
|
|
216
|
+
minScore?: number;
|
|
217
|
+
/** Rollouts to collect before stopping. Unset sweeps the whole pool. */
|
|
218
|
+
maxRollouts?: number;
|
|
219
|
+
/**
|
|
220
|
+
* Instances per rollout batch. Smaller batches stop closer to the moment
|
|
221
|
+
* enough rollouts exist, at the cost of less concurrency inside the adapter.
|
|
222
|
+
*/
|
|
223
|
+
batchSize?: number;
|
|
224
|
+
/** Ceiling on rollouts run. Defaults to one pass over `data`. */
|
|
225
|
+
maxMetricCalls?: number;
|
|
226
|
+
/**
|
|
227
|
+
* Ceiling on dollars this pass may spend, checked between batches. Rollout
|
|
228
|
+
* counts are a poor proxy for spend, and a caller bounding dollars cannot
|
|
229
|
+
* bound this pass from outside: it runs on its own evaluator.
|
|
230
|
+
*/
|
|
231
|
+
maxCostUsd?: number;
|
|
232
|
+
/** Shuffles `data` first, so rollouts are not all drawn from its head. */
|
|
233
|
+
rng?: Rng;
|
|
234
|
+
signal?: AbortSignal;
|
|
235
|
+
}): Promise<HarvestResult<Datum, Output>>;
|
|
236
|
+
//#endregion
|
|
237
|
+
//#region src/distillation.d.ts
|
|
238
|
+
/** A turn in a training example, in the shape trainers read. */
|
|
239
|
+
interface ChatMessage {
|
|
240
|
+
role: "system" | "user" | "assistant";
|
|
241
|
+
content: string;
|
|
242
|
+
}
|
|
243
|
+
interface TrainingExample {
|
|
244
|
+
messages: ChatMessage[];
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Turns one harvested rollout into the example to train on, or `null` to skip
|
|
248
|
+
* it. The callback exists because only the caller knows how to render a
|
|
249
|
+
* `Datum` — the library never sees inside one.
|
|
250
|
+
*
|
|
251
|
+
* It is also where the consequential decision lives: how much of the optimized
|
|
252
|
+
* candidate to leave in the input. Dropping it entirely moves the whole prompt
|
|
253
|
+
* into weights and gives up the ability to steer the model with text
|
|
254
|
+
* afterwards; keeping a short task statement distills away only the tokens the
|
|
255
|
+
* search accreted. See `docs/distillation.md` in this package.
|
|
256
|
+
*/
|
|
257
|
+
type TrainingExampleRenderer<Datum, Output> = (args: {
|
|
258
|
+
rollout: Rollout<Datum, Output>;
|
|
259
|
+
index: number;
|
|
260
|
+
}) => TrainingExample | null;
|
|
261
|
+
/**
|
|
262
|
+
* Serialize harvested rollouts as JSONL, one training example per line.
|
|
263
|
+
*
|
|
264
|
+
* The chat-messages shape rather than any one vendor's: it is what Axolotl,
|
|
265
|
+
* Together, Fireworks and the Hugging Face trainers all ingest, and the
|
|
266
|
+
* providers that read it outlive the ones that do not.
|
|
267
|
+
*
|
|
268
|
+
* Returns the text rather than writing it. Only `file-cache` touches the
|
|
269
|
+
* filesystem, and a caller uploading this straight to a provider should not
|
|
270
|
+
* have to round-trip it through a file to do so.
|
|
271
|
+
*/
|
|
272
|
+
declare function toTrainingJsonl<Datum, Output>(args: {
|
|
273
|
+
rollouts: readonly Rollout<Datum, Output>[];
|
|
274
|
+
render: TrainingExampleRenderer<Datum, Output>;
|
|
275
|
+
}): string;
|
|
276
|
+
//#endregion
|
|
139
277
|
//#region src/judge.d.ts
|
|
140
278
|
/** One thing the judge grades, and what a perfect answer looks like for it. */
|
|
141
279
|
interface JudgeCriterion {
|
|
142
280
|
name: string;
|
|
143
281
|
description: string;
|
|
282
|
+
/**
|
|
283
|
+
* Share of the instance score this criterion carries, relative to the other
|
|
284
|
+
* criteria. Default 1, which is the unweighted mean.
|
|
285
|
+
*
|
|
286
|
+
* 0 removes a criterion from the aggregate, not from the search. It is still
|
|
287
|
+
* graded and still recorded in `objectiveScores`, which
|
|
288
|
+
* `paretoSelector({ frontier: "objective" })` and `"hybrid"` build their
|
|
289
|
+
* selection fronts from — so a candidate leading a zero-weight criterion
|
|
290
|
+
* still earns parent selection under those. Under the default instance
|
|
291
|
+
* frontier, 0 is enough. For a number that can never steer the search,
|
|
292
|
+
* compute it outside the judge.
|
|
293
|
+
*/
|
|
294
|
+
weight?: number;
|
|
295
|
+
/**
|
|
296
|
+
* Grade, on the judge's own scale, that this criterion must reach for the
|
|
297
|
+
* instance to score at all. Below it the instance scores 0 whatever the
|
|
298
|
+
* other criteria said.
|
|
299
|
+
*
|
|
300
|
+
* A mean lets a search trade a hard requirement away: a candidate that tanks
|
|
301
|
+
* one non-negotiable criterion and aces three cosmetic ones outranks the
|
|
302
|
+
* incumbent that kept the rule. Anything a caller would not ship without is
|
|
303
|
+
* a gate rather than a term in the average.
|
|
304
|
+
*
|
|
305
|
+
* Enforce it once. A gate already makes the requirement non-negotiable, so a
|
|
306
|
+
* heavy `weight` on the same criterion redistributes score only among
|
|
307
|
+
* candidates that all cleared it — and pins that share of the aggregate near
|
|
308
|
+
* its ceiling, narrowing the range the search has left to move in. Gate it,
|
|
309
|
+
* then weight it low.
|
|
310
|
+
*
|
|
311
|
+
* @see docs/metric-preflight.md
|
|
312
|
+
*/
|
|
313
|
+
gate?: number;
|
|
144
314
|
}
|
|
145
315
|
type JudgePromptBuilder = (args: {
|
|
146
316
|
input: string;
|
|
@@ -218,4 +388,4 @@ declare function priceUsage(args: {
|
|
|
218
388
|
pricing?: TokenPricing;
|
|
219
389
|
}): RolloutUsage;
|
|
220
390
|
//#endregion
|
|
221
|
-
export { type Adapter, type BatchSampler, type BootstrapResult, type Budget, BudgetExhausted, type CachedScore, type Candidate, type Comparison, type ComparisonRun, type ComparisonSummary, type Deadline, type Demo, type DemoRenderer, type EvaluateArgs, type EvaluateBatchArgs, type EvaluateTracedArgs, type EvaluationBatch, type EvaluationCache, type EvaluationContext, type EvaluationEvent, type EvaluationPhase, type EvaluationSplit, type Evaluator, type Judge, type JudgeCriterion, type JudgePromptBuilder, type Optimizer, type OptimizerResult, type OptimizerTask, type RetryPolicy, type Rng, type RolloutUsage, type ScoreResult, type ScoredBatch, type TextModel, type TokenPricing, type UsageTotals, assertResumable,
|
|
391
|
+
export { type Adapter, type BatchSampler, type BootstrapResult, type Budget, BudgetExhausted, type CachedScore, type Candidate, type CandidateAccepted, type ChatMessage, type Comparison, type ComparisonRun, type ComparisonSummary, type Deadline, type Demo, type DemoRenderer, type EvaluateArgs, type EvaluateBatchArgs, type EvaluateTracedArgs, type EvaluationBatch, type EvaluationCache, type EvaluationContext, type EvaluationEvent, type EvaluationPhase, type EvaluationSplit, type Evaluator, type HarvestResult, type Judge, type JudgeCriterion, type JudgePromptBuilder, type Optimizer, type OptimizerEvent, type OptimizerResult, type OptimizerTask, type ReportableEvent, type Reporter, type RetryPolicy, type Rng, type Rollout, type RolloutUsage, type RunFinished, type RunWarning, type RunWarningCode, type ScoreResult, type ScoredBatch, type TextModel, type TokenPricing, type TrainingExample, type TrainingExampleRenderer, type UsageTotals, assertResumable, buildJudgePrompt, candidateFingerprint, compare, componentNames, costExhausted, createBudget, createDeadline, createEvaluator, createJudge, createMemoryCache, formatDemos, harvestFewShotExamples, harvestRollouts, isCandidateAccepted, isRunFinished, mapWithConcurrency, measuredMean, parseDemos, parseProposedText, priceUsage, requireMeasuredMean, resolveValidationSet, runFingerprint, seedScoreWarnings, toTrainingJsonl };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { C as componentNames, S as UsageTotals, _ as EvaluationPhase, a as RunFinished, b as ScoreResult, c as RunWarning, d as seedScoreWarnings, f as Adapter, g as EvaluationContext, h as EvaluationBatch, i as Reporter, l as RunWarningCode, m as EvaluateArgs, n as OptimizerEvent, o as isCandidateAccepted, p as Candidate, r as ReportableEvent, s as isRunFinished, t as CandidateAccepted, u as resolveValidationSet, v as EvaluationSplit, x as TextModel, y as RolloutUsage } from "./reporting-bq007_2z.mjs";
|
|
2
2
|
import { n as EvaluationCache, r as createMemoryCache, t as CachedScore } from "./cache-CuSo0NJ8.mjs";
|
|
3
3
|
import { t as Rng } from "./rng-BR5MOedA.mjs";
|
|
4
|
-
import { a as
|
|
5
|
-
import { a as EvaluateBatchArgs, c as Evaluator, d as costExhausted, f as createEvaluator, g as createBudget, h as Budget, i as BudgetExhausted, l as RetryPolicy, m as requireMeasuredMean, n as OptimizerResult, o as EvaluateTracedArgs, p as measuredMean, r as OptimizerTask, s as EvaluationEvent, t as Optimizer, u as ScoredBatch } from "./optimizer-
|
|
4
|
+
import { a as harvestFewShotExamples, i as formatDemos, n as Demo, o as parseDemos, r as DemoRenderer, t as BootstrapResult } from "./demos-ASsSXYXA.mjs";
|
|
5
|
+
import { a as EvaluateBatchArgs, c as Evaluator, d as costExhausted, f as createEvaluator, g as createBudget, h as Budget, i as BudgetExhausted, l as RetryPolicy, m as requireMeasuredMean, n as OptimizerResult, o as EvaluateTracedArgs, p as measuredMean, r as OptimizerTask, s as EvaluationEvent, t as Optimizer, u as ScoredBatch } from "./optimizer-Ds5mzYjz.mjs";
|
|
6
6
|
import { t as BatchSampler } from "./sampling-DFo_7RNJ.mjs";
|
|
7
7
|
//#region src/checkpoint.d.ts
|
|
8
8
|
/**
|
|
@@ -46,6 +46,10 @@ interface ComparisonRun {
|
|
|
46
46
|
bestScore: number;
|
|
47
47
|
testScore?: number;
|
|
48
48
|
metricCalls: number;
|
|
49
|
+
/** Rollouts this run got from the cache instead of paying for. */
|
|
50
|
+
cacheHits: number;
|
|
51
|
+
/** Calls to a proposal or reflection model, outside the metric budget. */
|
|
52
|
+
reflectionCalls: number;
|
|
49
53
|
costUsd: number;
|
|
50
54
|
stopReason: string;
|
|
51
55
|
}
|
|
@@ -58,12 +62,33 @@ interface ComparisonSummary {
|
|
|
58
62
|
maxScore: number;
|
|
59
63
|
meanMetricCalls: number;
|
|
60
64
|
meanCostUsd: number;
|
|
65
|
+
meanCacheHits: number;
|
|
66
|
+
meanReflectionCalls: number;
|
|
67
|
+
/**
|
|
68
|
+
* How many distinct values this entrant's score took across its seeds.
|
|
69
|
+
* 1 means every seed landed on the same number — the seed changed nothing
|
|
70
|
+
* about the outcome, whatever the search did internally with it.
|
|
71
|
+
*/
|
|
72
|
+
distinctScores: number;
|
|
61
73
|
/**
|
|
62
74
|
* How often the winner's margin over this entrant would arise if the two
|
|
63
|
-
* were equally good and each seed's outcome were a coin flip. Absent for
|
|
64
|
-
* winner itself
|
|
75
|
+
* were equally good and each seed's outcome were a coin flip. Absent for
|
|
76
|
+
* the winner itself, and also absent when every seed produced the exact
|
|
77
|
+
* same margin: a sign-flip test over n seeds is answering a question about
|
|
78
|
+
* n independent trials, and identical margins mean the seed never actually
|
|
79
|
+
* put that to the test — there was one realization, repeated. Reporting a
|
|
80
|
+
* p-value there would state a precision (as fine as 2^-n) that the run
|
|
81
|
+
* never earned, so it is withheld rather than printed misleadingly small.
|
|
65
82
|
*/
|
|
66
83
|
pValueVsWinner?: number;
|
|
84
|
+
/**
|
|
85
|
+
* `pValueVsWinner` after Holm-Bonferroni step-down across the other
|
|
86
|
+
* entrants in this same `compare()` call — the family the raw p-value
|
|
87
|
+
* would otherwise be read against in isolation. Absent wherever the raw
|
|
88
|
+
* p-value is: a withheld comparison has nothing to adjust, but it still
|
|
89
|
+
* occupies a slot in the family the other comparisons are corrected for.
|
|
90
|
+
*/
|
|
91
|
+
pValueVsWinnerHolm?: number;
|
|
67
92
|
}
|
|
68
93
|
interface Comparison {
|
|
69
94
|
/** Highest mean score. Read `pValueVsWinner` before believing it. */
|
|
@@ -85,7 +110,7 @@ interface Comparison {
|
|
|
85
110
|
* seed is constructor config and every optimizer here is deterministic given
|
|
86
111
|
* one — comparing two entrants at a single seed compares two anecdotes. It also
|
|
87
112
|
* leaves the task where the caller builds it, which is the only place the
|
|
88
|
-
* optimizer-specific parts of it (`reflect`, `cache`, `
|
|
113
|
+
* optimizer-specific parts of it (`reflect`, `cache`, `reporters`) are known.
|
|
89
114
|
*/
|
|
90
115
|
declare function compare<K extends string, Output = unknown>(args: {
|
|
91
116
|
entrants: Record<string, (args: {
|
|
@@ -136,11 +161,156 @@ declare function createDeadline(args: {
|
|
|
136
161
|
now?: () => number;
|
|
137
162
|
}): Deadline;
|
|
138
163
|
//#endregion
|
|
164
|
+
//#region src/harvest.d.ts
|
|
165
|
+
/**
|
|
166
|
+
* One rollout worth keeping: what went in, what the system produced, and how
|
|
167
|
+
* that output scored. Harvested, never written — the value of the pair is that
|
|
168
|
+
* the system actually produced the output and the metric actually rewarded it.
|
|
169
|
+
*/
|
|
170
|
+
interface Rollout<Datum = unknown, Output = unknown> {
|
|
171
|
+
input: Datum;
|
|
172
|
+
output: Output;
|
|
173
|
+
score: number;
|
|
174
|
+
}
|
|
175
|
+
interface HarvestResult<Datum, Output> {
|
|
176
|
+
rollouts: Rollout<Datum, Output>[];
|
|
177
|
+
/** Rollouts this cost. Harvesting is cheap, not free. */
|
|
178
|
+
metricCalls: number;
|
|
179
|
+
/**
|
|
180
|
+
* Tokens and dollars this cost. Harvesting runs on its own evaluator, so a
|
|
181
|
+
* caller that bounds spend has to fold these into its own totals.
|
|
182
|
+
*/
|
|
183
|
+
usage: UsageTotals;
|
|
184
|
+
/** Instances run, including the ones the metric did not reward. */
|
|
185
|
+
attempted: number;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Run a candidate over data and keep the rollouts the metric rewarded.
|
|
189
|
+
*
|
|
190
|
+
* The library's one paid collection primitive, with two consumers: a few-shot
|
|
191
|
+
* block wants four of these, and a distillation set wants thousands. Both are
|
|
192
|
+
* the same pass — run the candidate, score it, keep what cleared the bar — so
|
|
193
|
+
* both share the budget, retry and transient-failure handling that pass needs.
|
|
194
|
+
*
|
|
195
|
+
* Which data to sweep is the caller's decision and the consequential one. A
|
|
196
|
+
* validation set is the wrong choice: it is the set that selected the candidate,
|
|
197
|
+
* so the rollouts it yields are enriched for the candidate's fit to those
|
|
198
|
+
* instances rather than to the task. Prefer the training set, or a pool held
|
|
199
|
+
* out of the run entirely.
|
|
200
|
+
*/
|
|
201
|
+
declare function harvestRollouts<Datum, Trajectory, Output, K extends string = string>(args: {
|
|
202
|
+
adapter: Adapter<Datum, Trajectory, Output, K>;
|
|
203
|
+
/** The candidate to run. Usually a run's winner, sometimes the seed. */
|
|
204
|
+
candidate: Candidate<K>;
|
|
205
|
+
data: readonly Datum[];
|
|
206
|
+
/**
|
|
207
|
+
* Score a rollout must reach to be kept. Unset keeps every rollout the
|
|
208
|
+
* metric rewarded at all, which is what MIPROv2's bootstrapper does without
|
|
209
|
+
* a `metric_threshold`: it keeps a trace on any truthy score and only
|
|
210
|
+
* compares against a number once one is configured.
|
|
211
|
+
*
|
|
212
|
+
* Demanding a perfect score instead is the right call for a boolean metric
|
|
213
|
+
* and the wrong one for a graded metric, where it throws away every rollout
|
|
214
|
+
* that was most of the way there — which on a hard task is all of them.
|
|
215
|
+
*/
|
|
216
|
+
minScore?: number;
|
|
217
|
+
/** Rollouts to collect before stopping. Unset sweeps the whole pool. */
|
|
218
|
+
maxRollouts?: number;
|
|
219
|
+
/**
|
|
220
|
+
* Instances per rollout batch. Smaller batches stop closer to the moment
|
|
221
|
+
* enough rollouts exist, at the cost of less concurrency inside the adapter.
|
|
222
|
+
*/
|
|
223
|
+
batchSize?: number;
|
|
224
|
+
/** Ceiling on rollouts run. Defaults to one pass over `data`. */
|
|
225
|
+
maxMetricCalls?: number;
|
|
226
|
+
/**
|
|
227
|
+
* Ceiling on dollars this pass may spend, checked between batches. Rollout
|
|
228
|
+
* counts are a poor proxy for spend, and a caller bounding dollars cannot
|
|
229
|
+
* bound this pass from outside: it runs on its own evaluator.
|
|
230
|
+
*/
|
|
231
|
+
maxCostUsd?: number;
|
|
232
|
+
/** Shuffles `data` first, so rollouts are not all drawn from its head. */
|
|
233
|
+
rng?: Rng;
|
|
234
|
+
signal?: AbortSignal;
|
|
235
|
+
}): Promise<HarvestResult<Datum, Output>>;
|
|
236
|
+
//#endregion
|
|
237
|
+
//#region src/distillation.d.ts
|
|
238
|
+
/** A turn in a training example, in the shape trainers read. */
|
|
239
|
+
interface ChatMessage {
|
|
240
|
+
role: "system" | "user" | "assistant";
|
|
241
|
+
content: string;
|
|
242
|
+
}
|
|
243
|
+
interface TrainingExample {
|
|
244
|
+
messages: ChatMessage[];
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Turns one harvested rollout into the example to train on, or `null` to skip
|
|
248
|
+
* it. The callback exists because only the caller knows how to render a
|
|
249
|
+
* `Datum` — the library never sees inside one.
|
|
250
|
+
*
|
|
251
|
+
* It is also where the consequential decision lives: how much of the optimized
|
|
252
|
+
* candidate to leave in the input. Dropping it entirely moves the whole prompt
|
|
253
|
+
* into weights and gives up the ability to steer the model with text
|
|
254
|
+
* afterwards; keeping a short task statement distills away only the tokens the
|
|
255
|
+
* search accreted. See `docs/distillation.md` in this package.
|
|
256
|
+
*/
|
|
257
|
+
type TrainingExampleRenderer<Datum, Output> = (args: {
|
|
258
|
+
rollout: Rollout<Datum, Output>;
|
|
259
|
+
index: number;
|
|
260
|
+
}) => TrainingExample | null;
|
|
261
|
+
/**
|
|
262
|
+
* Serialize harvested rollouts as JSONL, one training example per line.
|
|
263
|
+
*
|
|
264
|
+
* The chat-messages shape rather than any one vendor's: it is what Axolotl,
|
|
265
|
+
* Together, Fireworks and the Hugging Face trainers all ingest, and the
|
|
266
|
+
* providers that read it outlive the ones that do not.
|
|
267
|
+
*
|
|
268
|
+
* Returns the text rather than writing it. Only `file-cache` touches the
|
|
269
|
+
* filesystem, and a caller uploading this straight to a provider should not
|
|
270
|
+
* have to round-trip it through a file to do so.
|
|
271
|
+
*/
|
|
272
|
+
declare function toTrainingJsonl<Datum, Output>(args: {
|
|
273
|
+
rollouts: readonly Rollout<Datum, Output>[];
|
|
274
|
+
render: TrainingExampleRenderer<Datum, Output>;
|
|
275
|
+
}): string;
|
|
276
|
+
//#endregion
|
|
139
277
|
//#region src/judge.d.ts
|
|
140
278
|
/** One thing the judge grades, and what a perfect answer looks like for it. */
|
|
141
279
|
interface JudgeCriterion {
|
|
142
280
|
name: string;
|
|
143
281
|
description: string;
|
|
282
|
+
/**
|
|
283
|
+
* Share of the instance score this criterion carries, relative to the other
|
|
284
|
+
* criteria. Default 1, which is the unweighted mean.
|
|
285
|
+
*
|
|
286
|
+
* 0 removes a criterion from the aggregate, not from the search. It is still
|
|
287
|
+
* graded and still recorded in `objectiveScores`, which
|
|
288
|
+
* `paretoSelector({ frontier: "objective" })` and `"hybrid"` build their
|
|
289
|
+
* selection fronts from — so a candidate leading a zero-weight criterion
|
|
290
|
+
* still earns parent selection under those. Under the default instance
|
|
291
|
+
* frontier, 0 is enough. For a number that can never steer the search,
|
|
292
|
+
* compute it outside the judge.
|
|
293
|
+
*/
|
|
294
|
+
weight?: number;
|
|
295
|
+
/**
|
|
296
|
+
* Grade, on the judge's own scale, that this criterion must reach for the
|
|
297
|
+
* instance to score at all. Below it the instance scores 0 whatever the
|
|
298
|
+
* other criteria said.
|
|
299
|
+
*
|
|
300
|
+
* A mean lets a search trade a hard requirement away: a candidate that tanks
|
|
301
|
+
* one non-negotiable criterion and aces three cosmetic ones outranks the
|
|
302
|
+
* incumbent that kept the rule. Anything a caller would not ship without is
|
|
303
|
+
* a gate rather than a term in the average.
|
|
304
|
+
*
|
|
305
|
+
* Enforce it once. A gate already makes the requirement non-negotiable, so a
|
|
306
|
+
* heavy `weight` on the same criterion redistributes score only among
|
|
307
|
+
* candidates that all cleared it — and pins that share of the aggregate near
|
|
308
|
+
* its ceiling, narrowing the range the search has left to move in. Gate it,
|
|
309
|
+
* then weight it low.
|
|
310
|
+
*
|
|
311
|
+
* @see docs/metric-preflight.md
|
|
312
|
+
*/
|
|
313
|
+
gate?: number;
|
|
144
314
|
}
|
|
145
315
|
type JudgePromptBuilder = (args: {
|
|
146
316
|
input: string;
|
|
@@ -218,4 +388,4 @@ declare function priceUsage(args: {
|
|
|
218
388
|
pricing?: TokenPricing;
|
|
219
389
|
}): RolloutUsage;
|
|
220
390
|
//#endregion
|
|
221
|
-
export { type Adapter, type BatchSampler, type BootstrapResult, type Budget, BudgetExhausted, type CachedScore, type Candidate, type Comparison, type ComparisonRun, type ComparisonSummary, type Deadline, type Demo, type DemoRenderer, type EvaluateArgs, type EvaluateBatchArgs, type EvaluateTracedArgs, type EvaluationBatch, type EvaluationCache, type EvaluationContext, type EvaluationEvent, type EvaluationPhase, type EvaluationSplit, type Evaluator, type Judge, type JudgeCriterion, type JudgePromptBuilder, type Optimizer, type OptimizerResult, type OptimizerTask, type RetryPolicy, type Rng, type RolloutUsage, type ScoreResult, type ScoredBatch, type TextModel, type TokenPricing, type UsageTotals, assertResumable,
|
|
391
|
+
export { type Adapter, type BatchSampler, type BootstrapResult, type Budget, BudgetExhausted, type CachedScore, type Candidate, type CandidateAccepted, type ChatMessage, type Comparison, type ComparisonRun, type ComparisonSummary, type Deadline, type Demo, type DemoRenderer, type EvaluateArgs, type EvaluateBatchArgs, type EvaluateTracedArgs, type EvaluationBatch, type EvaluationCache, type EvaluationContext, type EvaluationEvent, type EvaluationPhase, type EvaluationSplit, type Evaluator, type HarvestResult, type Judge, type JudgeCriterion, type JudgePromptBuilder, type Optimizer, type OptimizerEvent, type OptimizerResult, type OptimizerTask, type ReportableEvent, type Reporter, type RetryPolicy, type Rng, type Rollout, type RolloutUsage, type RunFinished, type RunWarning, type RunWarningCode, type ScoreResult, type ScoredBatch, type TextModel, type TokenPricing, type TrainingExample, type TrainingExampleRenderer, type UsageTotals, assertResumable, buildJudgePrompt, candidateFingerprint, compare, componentNames, costExhausted, createBudget, createDeadline, createEvaluator, createJudge, createMemoryCache, formatDemos, harvestFewShotExamples, harvestRollouts, isCandidateAccepted, isRunFinished, mapWithConcurrency, measuredMean, parseDemos, parseProposedText, priceUsage, requireMeasuredMean, resolveValidationSet, runFingerprint, seedScoreWarnings, toTrainingJsonl };
|