Is your feature request related to a problem? Please describe.
GCGAlgorithmConfig.random_seed is documented as the seed for Torch, NumPy, and Python randomness, but the current implementation only uses it when shuffling CSV input rows. Candidate sampling uses Torch randomness, target augmentation uses NumPy randomness, and annealing uses Python randomness without a per-run seeded source. Multiprocessing workers also do not receive deterministic derived seeds.
As a result, two runs with the same GCG configuration can follow different candidate and suffix trajectories. Concurrent runs can also interfere through process-global RNG state.
Describe the solution you'd like
Create a per-run RNG bundle derived from GCGAlgorithmConfig.random_seed and thread it through every stochastic GCG operation:
- a local
random.Random instance for annealing;
- a local
numpy.random.Generator for target preprocessing;
- explicit
torch.Generator instances for candidate sampling, derived deterministically per worker/device;
- deterministic worker seed derivation that does not depend on process launch order.
Avoid calling global random.seed, numpy.random.seed, or torch.manual_seed as the runtime mechanism because multiple GCG executions may share a process. Record the base seed and any derived worker seeds in the result or run metadata.
Acceptance criteria:
- Repeating a run with the same configuration, seed, hardware, and process topology produces the same sampled candidates, accepted controls, loss history, and final suffix.
- Concurrent runs do not change one another's random trajectories.
- Different seeds can produce different candidate trajectories.
- Tests cover single-model/single-prompt, multi-model, multi-prompt, and progressive model/goal execution.
- Existing custom sampling, loss, candidate-filter, and suffix-initializer extension points continue to work.
- Multi-model, multi-prompt, held-out evaluation, and progressive optimization behavior are preserved.
Describe alternatives you've considered, if relevant
Seeding the global Python, NumPy, and Torch RNGs at the start of execute_async is simpler, but it would make concurrent executions interfere with each other. Tests that manually call random.seed are also insufficient because they do not make the public random_seed setting effective throughout the implementation.
Additional context
This is a focused follow-up to #960 and should preserve the performance/generalization goals in #962. PR #2467 adds seeded state-transition tests but does not wire GCGAlgorithmConfig.random_seed through all stochastic runtime paths.
Is your feature request related to a problem? Please describe.
GCGAlgorithmConfig.random_seedis documented as the seed for Torch, NumPy, and Python randomness, but the current implementation only uses it when shuffling CSV input rows. Candidate sampling uses Torch randomness, target augmentation uses NumPy randomness, and annealing uses Python randomness without a per-run seeded source. Multiprocessing workers also do not receive deterministic derived seeds.As a result, two runs with the same GCG configuration can follow different candidate and suffix trajectories. Concurrent runs can also interfere through process-global RNG state.
Describe the solution you'd like
Create a per-run RNG bundle derived from
GCGAlgorithmConfig.random_seedand thread it through every stochastic GCG operation:random.Randominstance for annealing;numpy.random.Generatorfor target preprocessing;torch.Generatorinstances for candidate sampling, derived deterministically per worker/device;Avoid calling global
random.seed,numpy.random.seed, ortorch.manual_seedas the runtime mechanism because multiple GCG executions may share a process. Record the base seed and any derived worker seeds in the result or run metadata.Acceptance criteria:
Describe alternatives you've considered, if relevant
Seeding the global Python, NumPy, and Torch RNGs at the start of
execute_asyncis simpler, but it would make concurrent executions interfere with each other. Tests that manually callrandom.seedare also insufficient because they do not make the publicrandom_seedsetting effective throughout the implementation.Additional context
This is a focused follow-up to #960 and should preserve the performance/generalization goals in #962. PR #2467 adds seeded state-transition tests but does not wire
GCGAlgorithmConfig.random_seedthrough all stochastic runtime paths.