-
Notifications
You must be signed in to change notification settings - Fork 327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cross GPU device mapping feature #395
Comments
Related issue: huggingface/candle#2007 There was an attempt to do tensor parallelism: |
Hi @joshpopelka20 and @b0xtch! I just merged #462 which adds cross-GPU device mapping support (including for Python). I plan on implementing tensor parallelism, too, in the future. |
@EricLBuehler thanks for adding this feature. When using the pypi package, I'm getting this error:
I'm passing the CUDA_NVCC_FLAGS flag so not sure why it's saying to "recompile with -fPIC". These are the commands I'm using:
|
Can you try:
The -fPIC requirement may stem from your Linux distribution (some require -fPIE, I'll add this to the README)? |
Sorry, may not have been clear. I got that error when running with the flag set to '-fPIC'. I haven't tried running the code using the git repo and cargo. Do you want me to verify if that works? I'd guess they'd be the same though. |
Ah, ok. Not sure if we discussed this before, but what Linux distribution are you using? |
I'm using a Sagemaker Jupyter notebook so Amazon Linux. This is the distro info:
|
Adding some observations: When I run When I run
Running So it doesn't seem like compiling with both cudnn and flash-attn. |
I'm thinking the issue is related to mistralrs-core/build.rs file. I tried to add
but it didn't help. I think it's more of an issue with this line of code |
I added support for the NVCC flag envvar to that, so it should be seamless to use the envvar instead of changing the code, now.
It's in whatever the |
I added a pull request with a fix for the issue #471. Looks like it was a divide by zero issue. I didn't add any error message; I just let it continue to run. I ran llama and there was no issues. Also, I'm wondering if there should be other code added to the build.rs file. Like in the candle project:
I didn't have any issues with these, but someone else might be using those OSs in the future. |
I just merged #472 which adds this, thanks for pointing that out. |
Hi @joshpopelka20! I just merged #479 which adds a loading bar while loading the repeating layers. It would be great if you could install from source with maturin ahead of the PyPI rolling release (in ~2 days) to try it out! |
There were no issues building from source. Also, the 2 day delay is not an issue for me. Finally, I think the ask for this issue is complete. Would you like me to leave it open for adding tensor parallelism in the future? I'm not sure how you are tracking that. |
Great, just one thing to confirm: does the progress bar function to show the loading?
I'll create a separate issue, as device mapping is a bit different from tensor parallelism. |
Amazing stuff! The tensor parallelism I am guessing will be on the core candle repo? or do you plan to abstract that in some way under this repo? I have linked the device mapping issue with one in candle. huggingface/candle#2007 |
I plan on implementing the higher-level aspects here: the synchronization, the reduce ops, etc., which can all be done with the public Candle APIs. I actually have a fork of Candle which I maintain (https://github.com/EricLBuehler/candle). I have this because some of the features which make mistral.rs faster than Candle would not get merged quickly enough/fit that project's goal well. However, I do want to contribute any progress I make with tensor parallelism and so I'll try to contribute what makes sense! |
When I run
I don't normally run from the command line so I tried with the current pip package (mistralrs-cuda 0.1.22). That was able to load the model. |
Can you try to run that with RUST_BACKTRACE=1? |
I tried with |
#478 also seems to have an issue with that library as well. Though in a different file: cudarc-0.11.6/src/lib.rs Not sure if they're related. |
It seems to be throwing the error at this line:
From this https://users.rust-lang.org/t/how-to-prevent-thread-panicked-while-processing-panic-aborting/56508/2, it looks like it might be an issue with trying to unwrap that error string. I'll try to debug tonight. |
I cloned https://github.com/coreylowman/cudarc and added this code to the mistral.rs root Cargo.toml (on my box):
I removed the unwrap function and now I'm getting this error: Any suggestions on further debugging? I'll see if I can get more output tomorrow; right now, that error seems like another Cuda bug. |
I tried to run with And Is there something wrong for me? I use git version |
I was able to get more logging when I used panic in line 53 of cudarc/src/driver/result.rs
Not sure it's helpful though
|
I've narrowed it down to this line in mistralrs-pyo3/src/lib.rs for function not metal get_device(): let res = Device::cuda_if_available(0)?; The error handling isn't very good to know exactly what the error is. I'm trying some add'l error handling, but nothing has worked so far. |
The error is probably happening there because that is when the CUDA stuff will get initialized for the first time. |
CUDA operation failed with error: CUDA_ERROR_STUB_LIBRARY I think it's an issue with LD_LIBRARY_PATH pointing to cuda12.1. I tried to manually update it, but that didn't work. I'll get a ticket open with AWS. Also, I'm going to create a PR with cudarc to add the additional error handling. Think that'll be beneficial going forward. |
Just a quick update on this. AWS responded to me, but they'll need more time to troubleshoot. Hope this isn't holding anybody else up. |
I am getting an issue with |
@b0xtch your issue may not be the same. Are you seeing any CUDA error codes (https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__TYPES.html#group__CUDA__TYPES_1ggc6c391505e117393cc2558fff6bfc2e990696c86fcee1f536a1ec7d25867feeb)? Like these:
Sorry, the CUDA docs aren't very user friendly, but you'll find more in the above link. |
|
@chenwanqq mentioned on #472 that there may be a redundant copy. I'm looking into it. |
Don't know if that is the right place (sorry if not) but got 3 x RTX 3090 (Debian 12.5) and when launching :
That always try to fill the device 0 and leads CUDA_ERROR_OUT_OF_MEMORY (tried with different layer values but still the same). Any idea? |
Don't know if this will help, but this is the code that seems to be causing the issue (in mistralrs-core/src/pipeline/
Since &self.device() is the same each time, only its memory is going up during inference. This systems programming is new for me, so not sure what the fix could be. Is there a way to check for multiple devices and choose the one with the highest available memory? I think, ideally, some method that creates a device pool and splits the KV cache across the devices would be best. @Leflak, @b0xtch, @NiuBlibing not sure if you are seeing it error at the same place, but that's my guess. |
@joshpopelka20 yes, we store the KV cache on one GPU. This is because the attention operation necessitates that the Q, K and V matrices be on the same GPU. I'm not sure if there is a way to solve this other than KV cache quantization or other compression techniques. |
@EricLBuehler thanks for the reply. You can let me know if I'm wrong, but I think the prefix cache might help here. So for my use case, the prompt will mostly be the same each time (approx 9900 out of the 10K prompt tokens). What I noticed is on the first request, the KV cache grows on one GPU. Then on the prompt phase of the second request, I get OOM. Can we get the prefixes (matching on the 9900 tokens) and evict from the GPU prior to the prompt phase? I know this is use case specific and probably won't work for most use cases. Hopefully, there is some on-going research on how to split the KV cache across devices. |
I think this depends on the situation. Assuming you are running in interactive mode, this is expected as the chat interaction increases the KV cache size. Taking some quick measurements, the growth rate of the size is linear, which is what we would expect as the sequence length increases by some constant step.
In Rust, memory deallocation is not handled by a garbage collector and instead is coded into the executable with the Drop trait. This is called when something goes out of scope. Memory leakage is not a possibility because it is a static guarantee, but holding allocations for a long time is. So, if you run mistral.rs, the KV cache for a sequence is only dropped once it is finished. In the interactive mode, each time you send a request, a new sequence is created. The number of tokens will be higher and higher each time, increasing the prompt length and therefore the KV cache size. I think the main question is: are you using interactive mode? I will look into this though! |
Yes, for debugging the issue, I've been using interactive mode. I'll retry the debugger with a maturin build on Monday (though AWS is still looking into my issue when I do a "build from source" so that might not work). Thanks! Whenever you have the time to look at, it's no rush. Enjoy your weekend :) |
I was able to retest with this provided example: I think this issue has been fixed. I'll close it. Finally, @EricLBuehler thank you for your time and patience. The codebase is starting to make sense to me and reading research papers about transformers/llms is getting easier. I've spent most of my career working with Java and Javascript, so really excited to start my career transition to an "AI engineer" role. |
@joshpopelka20 glad that it works, I'm happy to help. Please let me know if you have any questions about mistral.rs or transformers/LLMs in general! |
I'm working with a long context model (gradientai/Llama-3-8B-Instruct-262k) that exceeds the memory of a single A100 GPU. While the model weights are loaded, when I try to run inference, I get CUDA Out of Memory exception.
Requesting a new feature to allow users to use cross GPU device mapping.
The text was updated successfully, but these errors were encountered: