Running the KV cache benchmark twice with the same seed and workload settings did not produce the same filenames or file contents.
Tested on current main (2dc78d3):
python3 kv-cache.py \
--model tiny-1b \
--num-users 1 \
--max-requests 4 \
--duration 30 \
--gpu-mem-gb 0 \
--cpu-mem-gb 0 \
--storage-capacity-gb 1 \
--generation-mode none \
--cache-dir "$CACHE_DIR" \
--seed 42 \
--output "$OUTPUT"
Both runs completed 4 requests and generated 1,243 tokens. Their file sizes matched, but their names and hashes differed:
run A:
conv_user_0000_1784555733870_turn_1.npy
141066368 bytes
sha256: 3a73b832...
run B:
conv_user_0000_1784555748474_turn_1.npy
141066368 bytes
sha256: 8e4412b2...
The immediate cause appears to be conversation.py:55, where the conversation ID contains the current wall-clock time. The ID becomes part of the cache filename and is also used when generating the file contents.
There are a few additional sources of nondeterminism:
- generator and processing threads share module-global RNGs;
- queue tie-breaking uses
time.time();
- concurrent requests may already be in flight when
--max-requests is reached.
For a fixed seed, configuration, input data, and request count, it would be useful to reproduce:
- request, conversation, and cache identities;
- relative filenames, file sizes, and contents;
- workload decisions such as token counts, prefix caching, and multi-turn behavior;
- the logical per-file read/write/delete pattern;
- the exact number of admitted requests.
This would still use the real storage backend. Latency, throughput, syscall chunking, physical block placement, and completion timing would remain nondeterministic.
Would the project be open to a PR adding this guarantee, either to --seed or through a separate deterministic-workload option?
Running the KV cache benchmark twice with the same seed and workload settings did not produce the same filenames or file contents.
Tested on current
main(2dc78d3):Both runs completed 4 requests and generated 1,243 tokens. Their file sizes matched, but their names and hashes differed:
The immediate cause appears to be
conversation.py:55, where the conversation ID contains the current wall-clock time. The ID becomes part of the cache filename and is also used when generating the file contents.There are a few additional sources of nondeterminism:
time.time();--max-requestsis reached.For a fixed seed, configuration, input data, and request count, it would be useful to reproduce:
This would still use the real storage backend. Latency, throughput, syscall chunking, physical block placement, and completion timing would remain nondeterministic.
Would the project be open to a PR adding this guarantee, either to
--seedor through a separate deterministic-workload option?