Closed reuank closed 5 months ago
There is one randomizer that's shared continuously across all generations (rng
in the llama_context
object). EDIT: That shouldn't have any effect at temperature 0, though... This sounds like some difference in order of operations affecting precision. (Vertical vs. horizontal vectorization, maybe. I don't know the implementation details here specifically.) (You may want to trace through the batching behaviour in the server to find out what happens there.)
EDIT2: It might be continuous batching, that's enabled by default. Currently doesn't seem to have any flag to disable it, but you can change the default in the source to see what effect that has on determinism. (See https://github.com/ggerganov/llama.cpp/pull/6358)
Hey @kaetemi, thank you for your comment. According to the server documentation, continuous batching is disabled by default. Is this outdated information then?
First of all, make sure that you're using a version that has this fix https://github.com/ggerganov/llama.cpp/pull/6835 because without it there is only a single RNG state across all slots.
On the latest master the results for multiple slots are still not 100% deterministic. The problem mainly has to do with the use of > 1 slots, see https://github.com/ggerganov/llama.cpp/pull/6950 . Generally speaking, floating point operations only return bit-for-bit identical results if the exact same operations are executed in the exact same way. However, the whole reason why using multiple slots is faster is because this is not done.
When using a single slot, I always get the same answer, but still small variations in the logits. They don't seem to be big enough to cause different tokens to be selected though.
To my knowledge that shouldn't be happening, is this still the case on the latest master commit?
This issue was closed because it has been inactive for 14 days since being marked as stale.
Hey there,
thank you for your great work on llama.cpp!
I am using it in my bachelors thesis to build a LLM benchmarking tool. To make use of big GPUs, I am running a llama.cpp server in the background, and generate HTTP requests with multiple threads. This way I get much faster execution times.
For my benchmarks it is important to get deterministic results when prompting the model. I therefore set the temperature to 0 and disable other samplers. When closely inspecting the returned completions and logits across multiple runs, I realised that they are, however, not deterministic.
I have created the proof of concept below, which I executed on an H100. It spawns a llama.cpp server with 8 slots, and sends the same prompt to each slot using multiple threads. I expected all completions to be identical, but they were not. When running the script multiple times, I get between 5 and 8 unique completion texts when using 8 slots. If everything were completely deterministic, there should only be a single unique completion text in this case.
When using a single slot, I always get the same answer, but still small variations in the logits. They don't seem to be big enough to cause different tokens to be selected though.
I am currently running llama.cpp version b2774. I experienced this behavior on my MacBook Pro M1, as well as on an H100 and an A100. I also got this behavior with different models and different quantizations. It seems to me that the output just gets more random the more slots I use.
Can anyone explain to me what is happening here? Is there a way to force the outputs to be deterministic? Am I missing something here?
I would really appreciate any help!
Best Leon