Skip to content

fix: pass the request seed to the sampler, and survive a negative one - #220

Merged
solderzzc merged 1 commit into
SharpAI:mainfrom
HamedShams:fix/seed-reaches-sampler
Oct 10, 2026
Merged

solderzzc merged 1 commit into
SharpAI:mainfrom
HamedShams:fix/seed-reaches-sampler

Conversation

@HamedShams

Copy link
Copy Markdown
Contributor

Closes #219.

What

  • The request seed now reaches the sampler. Both handlers set GenerateParameters.seed, which is what TopPSampler / CategoricalSampler actually use; the global MLXRandom.seed call stays for the paths that call MLXRandom directly.
  • A negative seed no longer crashes the process. UInt64(seed) trapped on it ("Negative value is not representable", Server.swift:2387); the new samplingSeed(_:) takes the bit pattern instead, so every distinct Int is still a distinct seed.

Behaviour without a seed is unchanged: the sampler keeps its entropy-seeded RandomState.

Why

The samplers draw from their own RandomState, seeded only through GenerateParameters.seed. Seeding MLX's global generator alone meant seed was accepted and silently ignored: the same request with seed: 42 three times gave three different answers. And since OpenAI's seed is a plain integer, a client sending -1 took the whole server down with one request (crash report in #219).

Verified

  • SamplingSeedTests (new): the Int → UInt64 mapping, and that two samplers built with the same GenerateParameters.seed draw the same tokens while different seeds differ. Red on main for the negative-seed case (trap) and green here.
  • tests/test-contract.sh gained two assertions: the same seeded request twice returns the identical message, and "seed": -1 answers 200 with /health still responding. Both fail on main (the second one by killing the server).
  • swift test --filter SwiftLMTests: 280 tests green locally (M1 Max, Xcode 27 / Swift 6.4). tests/test-contract.sh against the CI model (mlx-community/Qwen2.5-0.5B-Instruct-4bit): 12 passed, 0 failed, 2 skipped (the script's own tool-call / JSON capability skips).

The samplers draw from their own RandomState, which only
GenerateParameters.seed seeds. Seeding MLX's global generator alone left
the request's `seed` without effect: the same seeded request sampled
differently every time. Both handlers now set GenerateParameters.seed;
the global seed call stays for the paths that use MLXRandom directly.

UInt64(seed) trapped on a negative value, so `"seed": -1` took the whole
server down. samplingSeed(_:) takes the bit pattern instead.

Closes SharpAI#219.
@solderzzc
solderzzc merged commit 748c4bf into SharpAI:main Oct 10, 2026
15 checks passed
HamedShams added a commit to HamedShams/SwiftLM that referenced this pull request Oct 10, 2026
Both SharpAI#220 and this branch added a block before the results footer of
tests/test-contract.sh. The seed assertions keep their numbers (9, 9b);
the request-shape assertions move to 10 and 10b.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

seed is ignored by the sampler, and a negative seed crashes the server

2 participants