How to Achieve Reproducible Music Generations Using the Seed Parameter in ACE-Step UI
Set randomSeed to false and provide a concrete integer for the seed parameter to force deterministic output from the generation backend.
The fspecii/ace-step-ui repository provides a React-based interface for music generation that supports full reproducibility through its seed parameter architecture. When the randomSeed flag is disabled and a specific seed value is supplied, the backend initializes its random number generator with that integer—typically using torch.manual_seed—ensuring identical prompts and settings produce exactly the same audio waveform every time.
Understanding the Seed Architecture
The seed workflow flows through three critical components: the UI state in CreatePanel.tsx, the API definitions in services/api.ts, and the shared type system in types.ts.
State Management in CreatePanel.tsx
The seed controls reside in components/CreatePanel.tsx, where React state hooks manage user input. Lines 169-170 initialize the default values:
const [seed, setSeed] = useState(-1); // ← default unset
const [randomSeed, setRandomSeed] = useState(true);
When the user clicks Generate, the handleGenerate function (lines 978-1005) constructs the payload. The logic ensures that bulk jobs after the first always use a random seed:
randomSeed: randomSeed || i > 0, // true for bulk jobs after the first
seed: jobSeed, // user-supplied seed or random int
The GenerationParams Interface
The type definitions in services/api.ts (lines 66-78) declare the contract used across the application:
export interface GenerationParams {
// … other fields …
randomSeed?: boolean;
seed?: number;
// … other fields …
}
This interface ensures type safety when passing parameters from the UI to the generateApi.startGeneration wrapper, which ultimately transmits the data to the backend inference engine.
Configuring Deterministic Generation
Reproducibility requires explicit configuration either through the UI controls or direct API calls. The backend only guarantees identical output when randomSeed is explicitly false and seed contains a valid integer.
Using the UI Controls
To enable reproducible generation through the interface:
- Disable Random Seed – Click the lock icon beside the Seed field to toggle
randomSeedtofalse. - Enter a Seed – Input any 32-bit integer (e.g.,
42) into the number field. - Generate – The same seed persists across generations until modified.
The UI provides contextual guidance via a tooltip implemented at lines 2045-2048:
<span className="text-xs font-medium text-zinc-600 dark:text-zinc-400"
title="Fixing the seed makes results repeatable. Random is recommended for variety.">
{t('seed')}
</span>
Loading Seeds from Saved Parameters
When loading a previously exported JSON parameter file, the application automatically detects fixed seeds. Lines 468-470 in CreatePanel.tsx handle this logic:
if (data.seed !== undefined) {
setSeed(data.seed);
setRandomSeed(false);
}
This ensures that reloading a saved configuration restores the exact deterministic state used during the original generation.
Programmatic API Implementation
For headless or scripted workflows, pass the parameters directly to generateApi.startGeneration:
import { generateApi } from './services/api';
const params = {
customMode: true,
prompt: '',
lyrics: 'A gentle sunrise over the hills.',
style: 'Acoustic folk',
title: 'Morning Light',
ditModel: 'acestep-v15-turbo-shift3',
instrumental: false,
vocalLanguage: 'en',
bpm: 120,
keyScale: 'C major',
timeSignature: '4',
duration: 30,
inferenceSteps: 12,
guidanceScale: 9.0,
batchSize: 1,
randomSeed: false, // ← Disable randomization
seed: 123456, // ← Fixed deterministic seed
};
const token = 'YOUR_JWT_TOKEN';
generateApi.startGeneration(params, token)
.then(job => console.log('Job started:', job.jobId))
.catch(err => console.error('Generation error:', err));
Critical: Changing any other parameter—such as bpm, style, or lyrics—will produce different audio even with an identical seed, as these values alter the model's input conditioning.
Managing Seeds in Bulk Generation
When requesting multiple tracks (batchSize > 1), the application applies specific seed logic to prevent accidental duplication while maintaining flexibility:
| Job Index | Seed Behavior |
|---|---|
| First | Uses jobSeed from state if randomSeed is false |
| Subsequent | Generates Math.random() * 4294967295 (fresh random 32-bit integer) |
To achieve reproducibility across all bulk jobs, you must either:
- Generate single jobs iteratively in a script, incrementing the seed manually (e.g.,
seed: baseSeed + i) - Accept that only the first job will match your specified seed when using the UI's bulk mode
Summary
- Disable randomization by setting
randomSeedtofalsein your generation parameters. - Supply a concrete integer for the
seedfield—values like42or123456work as long as they remain consistent. - Maintain identical parameters across experiments; any changes to prompts, BPM, or model selection will alter the output despite a fixed seed.
- Handle bulk generation carefully, as the UI automatically randomizes seeds for jobs after the first to ensure variety.
Frequently Asked Questions
Why does the same seed produce different audio when I modify the prompt?
The seed controls the random number generator's initialization, but the generation pipeline is deterministic only for identical inputs. Changing the lyrics, style, bpm, or any other conditioning parameter alters the latent space traversal path, resulting in different audio output even with the same seed value.
Can I use the same seed across different ACE-Step models?
No, reproducibility is guaranteed only when using the identical model checkpoint (ditModel) and version. Different models have distinct parameter weights and noise scheduling algorithms, meaning a seed that produces a specific result in acestep-v15-turbo-shift3 will generate completely different audio in another model variant.
What is the valid range for seed values?
The application accepts any JavaScript number, but the backend typically interpret seeds as 32-bit unsigned integers (0 to 4,294,967,295). Negative values like the default -1 signal "unset" to the UI, but you should provide positive integers for deterministic generation. The bulk generation logic uses Math.random() * 4294967295 to stay within this range.
How do I verify that my generation is actually using the fixed seed?
Check the network payload in your browser's developer tools when clicking Generate. The request to the backend should contain "randomSeed": false and "seed": <your_number>. If randomSeed is true or the seed is -1, the backend will generate a random seed internally, breaking reproducibility.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →