You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While playing with implementing compression for copy/save state, I found a bug, which turned out to be reproducible in current main (41aee4d)
It seems to be model independent, and no parameters other than -ngl seem to make a difference either.
The first symptom happens for save-load-state, main and server, when -ngl equal to exactly N-1 is specified, basically this happens (generated output):
Hello there!###############################
Second symptom was found by accident, when fiddling with save-load-state for the purpose of implementing compression. Basically, if -ngl is N or bigger (all layers loaded),
The problem above, seems to disappear, however:
Not only save-load-state fails because generated text is different for both runs,
but also, after some tokens were sampled llama_copy_state_data outputs mostly empty array, which I only noticed because I tried to dump the state post generation, and suddenly started to get 99% compression ratio on that array. Because it turned out to be mostly zeroes.
All -ngl values between 0 - (N-2) work properly.
I have no way of testing on AMD so I do not know if it's Nvidia specific.
This sounds like the same problem I encountered in #2422
The problem comes from improperly stored/loaded kv cache. The last 2 layers offloaded to GPU are the V and K cache. If you only offload the V cache, you get garbage output. And if you offload both you get a problem with saving and loading state.
Edit: I wanted to add that this only happens when offloading all layers to the GPU with CUBLAS, because CLBLAST does not offload the kv cache as far as I know.
@staviq
I dived into the code a bit to see if I could somehow hack it into my utility. In ggml-cuda there are primitives to read back the tensor data, but it doesn't seem to be used anywhere (yet).
As the prompts are often very similar it would help a lot if I could reuse the kv cache from previous decoding steps.
I was confused by the llama_set_state_data() code in the llama.cpp file that temporarily allocates a temporary graph with "tensor_3d" and does some update stuff - instead of just loading the kv cache data directly into the right kv cache tensors. - So I think I am missing too much of the internals to mess around with them.
Also neither ggml_backend_tensor_copy() nor ggml_backend_tensor_set() and ggml_backend_tensor_get() seem to be used somewhere in the llama.cpp project, which made me suspicious and I did not dare to dabble with an unused API (without example usage).
Activity
WeirdConstructor commentedon Nov 7, 2023
This sounds like the same problem I encountered in #2422
The problem comes from improperly stored/loaded kv cache. The last 2 layers offloaded to GPU are the V and K cache. If you only offload the V cache, you get garbage output. And if you offload both you get a problem with saving and loading state.
Edit: I wanted to add that this only happens when offloading all layers to the GPU with CUBLAS, because CLBLAST does not offload the kv cache as far as I know.
staviq commentedon Nov 7, 2023
@WeirdConstructor
That pretty much coincides with my intuition, I m just not familiar enough with that part of the code.
Some kind of explicit back-sync function would pretty much solve it, and as it only needs to happen on state save/load.
They k/v split would probably have to be solved by rounding up n_gpu_layers so k/v cache it's always either offloaded or not offloaded.
OpenCL didn't have this problem, but suspiciously it said there are exactly 2 less layers "offloadable", which would now make sense.
WeirdConstructor commentedon Nov 7, 2023
@staviq
I dived into the code a bit to see if I could somehow hack it into my utility. In ggml-cuda there are primitives to read back the tensor data, but it doesn't seem to be used anywhere (yet).
My primary use case is: swapping prompts back and forth for evaluation in my prompt_runner branch - which I use for various benchmark purposes ( https://github.com/WeirdConstructor/llama.cpp/tree/prompt_runner/examples/prompt_runner ). It runs multiple prompts from a JSON file through inference and stores the results afterwards.
As the prompts are often very similar it would help a lot if I could reuse the kv cache from previous decoding steps.
I was confused by the llama_set_state_data() code in the
llama.cppfile that temporarily allocates a temporary graph with "tensor_3d" and does some update stuff - instead of just loading the kv cache data directly into the right kv cache tensors. - So I think I am missing too much of the internals to mess around with them.Also neither
ggml_backend_tensor_copy()norggml_backend_tensor_set()andggml_backend_tensor_get()seem to be used somewhere in the llama.cpp project, which made me suspicious and I did not dare to dabble with an unused API (without example usage).cebtenzzre commentedon Nov 7, 2023
cc @slaren
edit: This (the -ngl N-1 issue with all examples) is a regression somewhere between b1198 (ebc9608) and b1398 (4e82b2e).
edit 2: It's db3abcc
WeirdConstructor commentedon Nov 8, 2023
@cebtenzzre #2422 is older (July) than those commits (September/October).
cebtenzzre commentedon Nov 9, 2023
Since the -ngl N-1 issue was fixed, do we still need both this issue and #2422?
staviq commentedon Nov 9, 2023
@cebtenzzre
Something is still broken,
save-load-stateproduces garbage in the second run for both N and N-1 now (875fb42)N-1
N
WeirdConstructor commentedon Nov 9, 2023
Yes, it's still a problem, like I posted over in the PR: #3982 (comment)
save-load-state in combination with GPU offloading has been broken for a long time.
staviq commentedon Nov 9, 2023
Ok, I went through #2422 and it seems to describe the second part of this issue pretty well
So I think this can be marked as duplicate of #2422 and closed, as they are at this point redundant.
Duplicate #2422