Replay and determinism
Why every execution of a run produces the same bytes, and how the Replay button recomputes a run in your browser.
The invariant
A run’s output is a pure function of four things:
- the sealed weights
- the prompt
- the parameters: max tokens and temperature
- the seed
All four are on chain: the weights in the model’s weight accounts, the rest in the run account. Any two executions of the same run agree on every byte, whoever sends the turns and however many transactions the forward pass is split across.
One core on three targets
curta-core is one Rust crate that holds the model format, the resumable forward pass, the tokenizer, the sampler and the turn planner. The same source builds for three targets:
- the program (SBF)
- the CLI (native)
- the browser (WebAssembly)
Its arithmetic is integer-only: int8 weights, fixed-point activations, lookup tables. Bit-exact across targets. Models and the weight format describes the format that carries it.
Sampling on chain from the seed
The program samples each token itself. At temperature zero the sampler takes the token with the highest score. Above zero it applies the run’s temperature in fixed point, sums integer exponentials of the scores over the whole vocabulary, and draws from an xorshift64* generator seeded with the run’s seed. Tokenizing the prompt and decoding tokens to text happen in the program too.
The same seed with the same model, prompt and parameters produces the same tokens.
Replay on a run’s page
- Open a run from /runs and press Replay.
- The browser reads the model’s weights from the chain.
- The WebAssembly build of
curta-corerecomputes the run from its prompt, parameters and seed: the tokenization of the prompt and every forward pass. - Each token is marked as matching the chain’s as it is computed.
Replay sends no transaction and asks for no signature.
Replay from code
The SDK’s replay call is an async generator. It reads the run and the model’s weight accounts over RPC, runs the same WebAssembly core, and yields one object per generated token.
for await (const token of curta.replay(runAddress)) {
console.log(token.index, token.token, token.matches, token.text)
}| Field | Value |
|---|---|
| index | The token’s position in the output. |
| token | The token id the replay computed. |
| chainToken | The token id the run account holds at that position. |
| matches | Whether the two are equal. |
| text | The output text the replay has produced so far. |
The call needs a connection and no wallet. The client keeps a model’s weights after the first read, so a second replay on the same model starts at once.