3 ms·
I notice that the CUDA example uses C++. I had not planned to publish my own work in this area yet (as I am still working on it), but if anyone wants fast llama
by ryao 2y ago
I notice that the CUDA example uses C++. I had not planned to publish my own work in this area yet (as I am still working on it), but if anyone wants fast llama inference using CUDA in C, here are some files:
https://bpa.st/CA6A https://bpa.st/CA6A
https://bpa.st/WOSA https://bpa.st/WOSA
It is a fork of:
https://github.com/jameswdelancey/llama3.c https://github.com/jameswdelancey/llama3.c
I am compiling and running it this way:
nvcc -ptx -arch=sm_86 rung.cu -o rung.ptx
gcc -I/opt/cuda/targets/x86_64-linux/include -L/opt/cuda/lib64 -O3 -g -lcuda -lcublas -lcudart -lm -lmvec -o rung rung.c
./rung "llama3_8b_base.bin" -z "tokenizer.bin" -t 0 -i "Once upon a time"
I am getting around 48 to 49 tokens per second with bf16 on my 3090 Ti from this. Oddly, llama.cpp only gets around 1 token per second with bf16, but it gets around 51 to 52 tokens per second with fp16. I suspect the performance gap would close if I use CUDA graphs.
The code is ugly in comparison to the original and I am not finished optimizing it, which is why I have not yet pushed it to a GitHub branch. I still have a few ways to reduce the amount of communication between the GPU and CPU per token, before using CUDA graphs. In particular, using the batched API for computing K and V, prefilling an array of pointers for the batched API across all layer iterations (such that all CPU to GPU pointer copies for the batched API are aggregated) and a few opportunities for kernel fusion, especially in rmsnorm after I figure out how to calculate the sum of squares quickly without cublas. I also have yet to try using Nvidia’s profiler.
Technically, CUDA C is really extended C++, but I am using a C-like subset of C++ for the device code. For the host code, I have written it in ANSI C. There are a few artifacts (the __host__ and __device__ keywords) from an earlier version where I had tried using CUDA C before I realized it was really extended C++ and not extended C, but those are trivial to remove (and will be removed before I push it to a branch). It should be possible to compile the device code with Clang instead of Nvidia’s compiler to use a fully open source toolchain, although I have yet to try it.
I have another fork here that uses the MKL to make the prompt processing portion run faster:
https://github.com/ryao/llama3.c https://github.com/ryao/llama3.c
When I am happy with the CUDA version, I will either push it to a branch or to its own set of files in master.
- reasonableklout 2y agoThank you for sharing! Would've loved to peek at your CUDA code but looks like it's gone now. Looking forward to seeing the full version when it's finished.
- ryao 2y agoAsk and you shall receive: https://github.com/ryao/llama3.c/commit/dc27f2b1c6884c72bd4bd3d8409a94bd12fdcaaf https://github.com/ryao/llama3.c/commit/dc27f2b1c6884c72bd4b... It is still a WIP, but the CUDA kernels are unlikely to see much improvement for a while as I had gone over them with a fine toothed comb for performance in the past few days. The C code is more likely where I will be making improvements. For example, I need to switch to a structure to stop abusing an array of void pointers for the cudaMemcpy() aggregration trick for the cublasGemmBatchedEx() calls. The current version is performing either on par to or slightly better than llama.cpp's F16 codepath on my 3090 Ti, and I have not even implemented CUDA graphs yet. Both get around 53 tokens per second, although on really good runs, I have seen my code do 54 tokens per second and I have not seen that from llama.cpp so far.
- reasonableklout 2y agoVery cool! I have been bedridden and unable to do much work the last few days but it will be cool to dig into this.
- ryao 2y agoI hope you feel better soon. If you want to get in touch in the future after we have both stoped checking this thread, you can find my email on one of my commits on GitHub.
- reasonableklout 2y agoThanks, will do!