rllama
App Listed Dormant
Pure Rust implementation of LLaMA-family of models, executable
- Downloads
- 1
- Dependents
- Not applicable
- Stars
- 553
- Forks
- 33
- Contributors
- 3
- Commits
- 90
- Latest release
- 0.3.0 ·
About
RLLaMA is a pure Rust implementation of LLaMA large language model inference..
Supported features
- Uses either
f16andf32weights. - LLaMA-7B, LLaMA-13B, LLaMA-30B, LLaMA-65B all confirmed working
- Hand-optimized AVX2 implementation
- OpenCL support for GPU inference.
- Load model only partially to GPU with
--percentage-to-gpucommand line switch to run hybrid-GPU-CPU inference. - Simple HTTP API support, with the possibility of doing token sampling on client side
- It can load
Vicuna-13Binstruct-finetuned model (although currently there is no nice UX).
Performance
The current performance is as follows:
Read the full README
Pure Rust implementations:
LLaMA-7B: AMD Ryzen 3950X: 552ms / token f16 (pure Rust)
LLaMA-7B: AMD Ryzen 3950X: 1008ms / token f32 (pure Rust)
LLaMA-13B: AMD Ryzen 3950X: 1029ms / token f16 (pure Rust)
LLaMA-13B: AMD Ryzen 3950X: 1930ms / token f32 (pure Rust)
LLaMA-30B: AMD Ryzen 5950X: 2112ms / token f16 (pure Rust)
LLaMA-65B: AMD Ryzen 5950X: 4186ms / token f16 (pure Rust)
OpenCL (all use f16):
LLaMA-7B: AMD Ryzen 3950X + OpenCL RTX 3090 Ti: 216ms / token (OpenCL on GPU)
LLaMA-7B: AMD Ryzen 3950X + OpenCL Ryzen 3950X: 680ms / token (OpenCL on CPU)
LLaMA-13B: AMD Ryzen 3950X + OpenCL RTX 3090 Ti: 420ms / token (OpenCL on GPU)
LLaMA-13B: AMD Ryzen 3950X + OpenCL Ryzen 3950X: 1232ms / token (OpenCL on CPU)
LLaMA-30B: AMD Ryzen 5950X + OpenCL Ryzen 5950X: 4098ms / token (OpenCL on CPU)
Scroll to the bottom of this README.md to see benchmarks over time.
Screenshot

Install
You can install with cargo tool. RLLaMA uses intrinsics extensively and you
likely need to enable them to install the executable.
RUSTFLAGS="-C target-feature=+sse2,+avx,+fma,+avx2" cargo install rllama
There is a .cargo/config.toml inside this repository that will enable these
features if you install manually from this Git repository instead.
Install (Docker path)
There is a Dockerfile you can use if you'd rather just get started quickly and
you are familiar with docker. You still need to download the models yourself.
For CPU-only docker support:
docker build -f ./.docker/cpu.dockerfile -t rllama .
docker run -v /models/LLaMA:/models:z -it rllama \
rllama --model-path /models/7B \
--param-path /models/7B/params.json \
--tokenizer-path /models/tokenizer.model \
--prompt "hi I like cheese"
Replace /models/LLaMA with the directory you've downloaded your models to.
The :z in -v flag may or may not be needed depending on your distribution
(I needed it on Fedora Linux)
For GPU-enabled docker support with nvidia:
Follow the instructions here.
LLaMA weights
Refer to https://github.com/facebookresearch/llama/ As of now, you need to be approved to get weights.
For LLaMA-7B make sure, you got these files:
* 7B/consolidated.00.pth
* 7B/params.json
* tokenizer.model
The consolidated.00.pth is actually a zip file. You need to unzip it:
$ cd 7B
$ unzip consolidated.00.pth
$ mv consolidated consolidated.00
If you are using a larger model like LLaMA-13B, then you can skip the last step
of renaming the consolidated directory.
You should now be ready to generate some text.
Example
Run LLaMA-7B with some weights casted to 16-bit floats:
rllama --tokenizer-path /path/to/tokenizer.model \
--model-path /path/to/LLaMA/7B \
--param-path /path/to/LLaMA/7B/params.json \
--f16 \
--prompt "The meaning of life is"
Use rllama --help to see all the options.
Partially load model to GPU
rllama can load only some of the transformer blocks to GPU. There is a
command line argument:
--percentage-to-gpu <value between 0 and 1, defaults to 1>
1 means 100% and 0 means 0%. Values in-between load the model partially to GPU.
You can use this to load LLaMA-13B or Vicuna-13B on a consumer GPU of 24
gigabytes at around --percentage-to-gpu 0.9 before it fails to out-of-memory
error (if there are no competing programs on the computer that use GPU memory).
Interactive mode
There is a simple experimental interactive mode to try force a type of back-and-forth discussion with the model.
rllama ... --start-interactive \
--interactive-system-prompt "Helpful assistant helps curious human." \ # (optional)
--interactive-prompt-postfix " ###Assistant:" \ # (optional)
--interactive-stop "###Human: " # (optional)
In this mode, you need to type your prompt before the AI starts doing its work.
If the AI outputs token sequence given in --interactive-stop (defaults to
###Human:) then it will ask for another input.
The defaults match Vicuna-13B model:
--interactive-system-prompt "A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions."
--interactive-prompt-postfix " ###Assissant:"
--interactive-prompt-prefix " "
--interactive-stop "###Human:"
--interactive-prompt-postfix is appended automatically to your typed text and
--interactive-prompt-prefix is appended to the start of your typed text.Here
is an example of interactive mode command line with the default settings:
rllama --f16 \
--param-path /models/vicuna13b/params.json \
--model-path /models/vicuna13b \
--tokenizer-path /stonks/LLaMA/tokenizer.model \
--start-interactive
As of writing of this, the output is not formatted prettily for chat and there is no visual indication of when you are supposed to be typing. That will come later.
Inference server
rllama can run in an inference server mode with a simple HTTP JSON API. You
need to enable server features for this.
cargo build --release --features server
The command line flags for this are:
--inference-serverusing this will turn on the inference server.--inference-server-portsets the port. Default port is 8080.--inference-server-hostsets the host. The default host is 127.0.0.1.--inference-server-max-concurrent-inferencessets how many concurrent requests are allowed to be actively doing inference at the same time. The default is 5.--inference-server-api-pathsets which path servers the API requests. The default path is/rllama/v1/inference--inference-server-prompt-cache-sizesets how many previous prompt calculations should be cached. Default is 50. This speeds up token generation for prompts that were already requested before, however it also increases memory use as the cache gets more full.--inference-server-exit-after-one-querywill make the server exit with exit code 0 after it has served one HTTP query. This is used for troubleshooting and experiments.
Prompts and flags related to token sampling are all ignored in inference server mode. Instead, they are obtained from each HTTP JSON API request.
Inference server API
There is an examples/api_hello_world.py for a minimal API use example.
POST /rllama/v1/inference
Expects a JSON body and Accept: application/json or Accept: text/jsonl.
The expected JSON is as follows:
{
"temperature": <number, optional>
"top_k": <integer, optional, default 20>
"top_p": <number, optional, default: 1.0>
"repetition_penalty": <number, optional, default: 1.0>
"stop_at_end_token": <bool, optional, default: true>
"max_seq_len": <integer, optional, default: 1024. Clamped to
be at highest the same as --max-seq-len command line option.>
"max_new_tokens": <integer, optional, default: 1024>
"no_token_sampling": <bool, optional, default: false>
"prompt": <string, required>
}
The form of the response depends on if no_token_sampling is set to true or false. The
response is in JSONL, i.e. multiple JSON dictionaries, separated by newlines.
no_token_sampling can turn off rllama's own token sampling. In this case,
the probabilities for every token are returned instead.
When no_token_sampling = false:
{<token string>: {"p": <number>, "is_end_token": bool, might not be present}}
tokencontains the new token to be appended to output. It does not include string you fed to the system originally.pis the probability that this token was chosen. For example, if this value is 0.1, it means that this particular token had 10% chance of being selected with the current token sampling settings.is_end_tokenistrueis the given token signifies end of output. This field is not present otherwise.
When no_token_sampling = true:
{<token string>: {"p": <number>, "is_end_token": bool, might not be present} \
,<token string>: {"p": <number>, "is_end_token": bool, might not be present} \
,...}
If you want to implement your own token sampling, you may want to set
max_new_tokens=1 and stop_at_end_token=false to suppress rllama's own
sampling behavior entirely.
rllama internally caches recently queried prompts and the intermediate
computations so that it's able to continue off quickly if you issue a query
that is either the same as a previous query or a continuation of one.
How to turn on OpenCL
Use opencl Cargo feature.
RUSTFLAGS="-C target-feature=+sse2,+avx,+fma,+avx2" cargo install rllama --features opencl
rllama --tokenizer-path /path/to/tokenizer.model \
--model-path /path/to/LLaMA/7B \
--param-path /path/to/LLaMA/7B/params.json \
--opencl-device 0 \
--prompt "The meaning of life is"
With opencl feature, there is also another argument, --opencl-device that
takes a number. That number selects Nth OpenCL device found on the system. You
can see the devices in the output when you run the program (e.g. see the
screenshot below).
Weights are always cast to 16-bit floats for OpenCL.
Notes and future plans
This is a hobby thing for me so don't expect updates or help.
- There are various BLAS libraries like CLBlast to speed up matrix multiplication that probably outperform my handwritten code.
- I've heard there is some thing called Tensor Cores on nVidia GPUs. Not accessible with OpenCL. But might be accessible on Vulkan with a an extension. Or with cuBLAS.
Benchmarks
I'm trying to track that I'm making this faster and not slower.
For 50-length sequence generation:
cargo run --release --
--model-path /LLaMA/13B \
--param-path /LLaMA/13B/params.json \
--tokenizer-path /LLaMA/tokenizer.model \
--prompt "Computers are pretty complica" --max-seq-len 50
# commit c9c861d199bd2d87d7e883e3087661c1e287f6c4 (13 March 2023)
LLaMA-7B: AMD Ryzen 3950X: 1058ms / token
LLaMA-13B: AMD Ryzen 3950X: 2005ms / token
# commit 63d27dba9091823f8ba11a270ab5790d6f597311 (13 March 2023)
# This one has one part of the transformer moved to GPU as a type of smoke test
LLaMA-7B: AMD Ryzen 3950X + OpenCL RTX 3090 Ti: 567ms / token
LLaMA-7B: AMD Ryzen 3950X + OpenCL Ryzen 3950X: 956ms / token
LLaMA-13B: AMD Ryzen 3950X + OpenCL RTX 3090 Ti: 987ms / token
LLaMA-13B: AMD Ryzen 3950X + OpenCL Ryzen 3950X: 1706ms / token
# commit 35b0c372a87192761e17beb421699ea5ad4ac1ce (13 March 2023)
# I moved some attention stuff to OpenCL too.
LLaMA-7B: AMD Ryzen 3950X + OpenCL RTX 3090 Ti: 283ms / token
LLaMA-7B: AMD Ryzen 3950X + OpenCL Ryzen 3950X: 679ms / token
LLaMA-13B: AMD Ryzen 3950X + OpenCL RTX 3090 Ti: <ran out of GPU memory>
LLaMA-13B: AMD Ryzen 3950X + OpenCL Ryzen 3950X: 1226ms / token
# commit de5dd592777b3a4f5a9e8c93c8aeef25b9294364 (15 March 2023)
# The matrix multiplication on GPU is now much faster. It didn't have that much
# effect overall though, but I got modest improvement on LLaMA-7B GPU.
LLaMA-7B: AMD Ryzen 3950X + OpenCL RTX 3090 Ti: 247ms / token
LLaMA-7B: AMD Ryzen 3950X + OpenCL Ryzen 3950X: 680ms / token
LLaMA-13B: AMD Ryzen 3950X + OpenCL RTX 3090 Ti: <ran out of GPU memory>
LLaMA-13B: AMD Ryzen 3950X + OpenCL Ryzen 3950X: 1232ms / token
LLaMA-30B: AMD Ryzen 5950X + OpenCL Ryzen 5950X: 4098ms / token
# commit 3d0afcf24309f28ec540ed7645c35400a865ad6f (17 March 2023)
# I've been focusing on making the ordinary non-OpenCL CPU implementation
# faster and I got some gains, most importantly from multithreading.
# There is Float16 support now, so I've added f16/f32 to these tables:
#
# I also managed to run LLaMA-65B for the first time.
LLaMA-7B: AMD Ryzen 3950X: 552ms / token f16
LLaMA-7B: AMD Ryzen 3950X: 1008ms / token f32
LLaMA-13B: AMD Ryzen 3950X: 1029ms / token f16
LLaMA-13B: AMD Ryzen 3950X: 1930ms / token f32
LLaMA-30B: AMD Ryzen 5950X: 2112ms / token f16
LLaMA-65B: AMD Ryzen 5950X: 4186ms / token f16
# commit f5328ab5bd62fe9bd930539382b13e9033434a0b (5 April 2023)
# I've worked on making Vicuna-13B runnable and added an option to only
# partially use GPU. Improved one of the OpenCL kernels:
LLaMA-7B: AMD Ryzen 3950X + OpenCL RTX 3090 Ti: 420ms (at 90%/10% GPU/CPU split)
LLaMA-13B: AMD Ryzen 3950X + OpenCL RTX 3090 Ti: 216ms (at 100% GPU)
Compatibility
- Runs on
- GPU support unknown
What shows it
- no dependency or feature matches a backend row
- Native code
- Optional
- Binds native code: cl-sys (feature opencl)
- Python bindings
- No Python binding crate found
- License
- AGPL-3.0
Compare with similar projects
Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days. ML Rust runs this catalogue, so its closest project always gets a row.
| Project | Downloads | Dependents | Stars | Latest release | Runs on (GPU) | Native code | License |
|---|---|---|---|---|---|---|---|
|
Pure Rust implementation of LLaMA-family of models, executable |
1 downloads over 30 days | Not applicable | 553 | 0.3.0 | GPU support unknown | Binds native code: cl-sys (feature opencl) | AGPL-3.0 |
|
llama-cpp-rs Featured
llama.cpp bindings for Rust Also in Run and serve models. |
341,382 downloads over 30 days | 98 | 665 | 0.1.161 | CUDA, WebGPU, Metal, ROCm, Vulkan | Binds native code: llama. Build uses a native toolchain: bindgen, cc, cmake | Apache-2.0 OR MIT |
|
llama-gguf Listed
A high-performance Rust implementation of llama.cpp - LLM inference engine with full GGUF support Also in Build LLM apps and agents. |
1,787 downloads over 30 days | 3 | 21 | 0.14.0 | CUDA, Metal, Vulkan | Binds native code: hailort-sys (feature hailo), libsqlite3-sys (feature rag-sqlite) | Apache-2.0 OR MIT |
|
oxionnx Listed
Pure Rust ONNX inference engine — zero C/C++ dependencies Also in Run and serve models. |
550 downloads over 30 days | 24 | 20 | 0.1.7 | CUDA, WebGPU | No native code found | Apache-2.0 |
|
Inference server for LLMs, speech and embeddings: OpenAI-compatible routes with streaming, plus speech synthesis (TTS) and transcription (ASR). Serves Llama, Mistral, Qwen, Mamba2, MLA+MoE and hybrid models from SafeTensors, AWQ, GPTQ and GGUF. Also in Build LLM apps and agents. |
8 binary downloads per release | Not applicable | 7 | 0.7.1 | CUDA, WebGPU | Binds native code: ring (feature distributed) | Apache-2.0 |
|
oxibonsai Listed
Pure Rust 1-bit LLM inference engine for PrismML Bonsai models — umbrella crate Also in Build LLM apps and agents. |
1 downloads over 30 days | 0 | 137 | 0.2.3 | CUDA, Metal | No native code found | Apache-2.0 |
|
furnace New
Fast, unified, Rust-native, Axum-compatible inference endpoints and nervous system for tensor models and LLMs: KServe / Triton and OpenAI APIs from one pure-Rust server Also in Build LLM apps and agents. |
241 downloads over 30 days | 0 | 66 | 0.16.2 | CUDA, WebGPU, Metal | No native code found | MIT |
All projects in Build LLM apps and agentsAll projects in Run and serve models
Why ListedNo archive, New or Featured rule places it, so it is Listed.
What it lacks for Featured
- The project is dormant and not finished. Dormancy rule
What else the check found
- The last activity is on 9 Apr 2023, 1310 days ago. That reaches the 365 days the rules expect, so the project is dormant. Dormancy rule
- The oldest outside issue waits 1304 days for a reply, past the limit of 270. No maintainer replied in 365 days. Rot signals rule
Not measured: Unpatched vulnerabilities past the grace window.
Exact rules: Listed, Featured app. The check on applied thresholds version 9.
Every rule outcome, as the check records it
expected-interval: app: E = 365 daysdormancy: last activity 2023-04-09, 1310 days ago, E = 365: dormantrot: oldest unanswered issue 1304 days (limit 270), no maintainer reply in 365 daysfeatured: not featured: dormant and not stablelisted: listed: no archive, new or featured rule applies
Measurements and sources
Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.
Sources6 sources
- Description: the crates.io description
- crates.io database dump, fetched
- GitHub repository, fetched
- crates.io package, fetched
- GitHub releases, fetched
- GitHub contributors, fetched
AdoptionNot measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Active dependents | Not measured | Yes | ||
| New dependents (365 days) | Not measured | Yes | ||
| Peak active dependents | Not measured | Yes | ||
| Active dependents as a share of the peak | Not measured | Yes | ||
| Binary downloads per release | Not measured | Yes |
MaintenanceLatest human commit: 3 years ago4 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Latest human commit | 2023-04-09 | GitHub repository | Yes | |
| Latest release | 2023-03-18 | crates.io database dump | Yes | |
| First release | 2023-03-18 | crates.io database dump | Yes | |
| Latest version | 0.3.0 | crates.io database dump | No | |
| Days the oldest outside issue waits for a reply | 1304 | GitHub repository | Yes | |
| Maintainer replies over 365 days | 0 | GitHub repository | Yes | |
| Repository archived | false | GitHub repository | Yes | |
| Repository gone | false | GitHub repository | Yes | |
| Release commit or manifest in the repo | true | crates.io package | No | |
| Published docs | Not measured | Yes | ||
| Latest release fails cargo check | Not measured | Yes | ||
| Build check date | Not measured | Yes | ||
| Build check toolchain | Not measured | Yes |
SecurityNot measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Unpatched vulnerabilities past the grace window | Not measured | Yes | ||
| RustSec unmaintained advisory | Not measured | Yes | ||
| Deprecation notice | Not measured | Yes | ||
| Deprecated requirement | Not measured | Yes |
Distribution3 releases, 1 downloads over 30 days6 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Releases | 3 | crates.io database dump | No | |
| Downloads over 30 days | 1 | crates.io database dump | No | |
| Binary downloads over the last 3 releases | 0 | GitHub releases | Yes | |
| Homebrew installs on request over 365 days | Not measured | Yes | ||
| Repology repository families | Not measured | Yes | ||
| Docker pull growth over 90 days | Not measured | Yes | ||
| Docker pulls at the growth baseline | Not measured | Yes | ||
| Every version a prerelease | false | crates.io database dump | Yes | |
| Every version 0.0.x | false | crates.io database dump | Yes | |
| Every version yanked | Not measured | Yes | ||
| Crate deleted from crates.io | Not measured | Yes |
Repository553 stars, 33 forks, 3 contributors, 90 commits. Stars alone never qualify a project.
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| GitHub stars | 553 | GitHub repository | Yes — one part of the repository route | |
| GitHub forks | 33 | GitHub repository | Yes — one part of the repository route | |
| Contributors with a GitHub account | 3 | GitHub contributors | Yes — one part of the repository route | |
| Commits on the default branch | 90 | GitHub repository | No | |
| Repository's main crate left out of the entry | none | crates.io database dump | Yes |
Facts that never count
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| License | AGPL-3.0 | crates.io database dump | No | |
| Runs on, from listed crates and their direct dependencies | GPU support unknown | crates.io database dump | No | |
| What shows each backend | no dependency or feature matches a backend row | crates.io database dump | No | |
| Native code, from listed crates and their dependencies | Binds native code: cl-sys (feature opencl) | crates.io database dump | No | |
| Python bindings, from direct dependencies of listed crates | No Python binding crate found | crates.io database dump | No | |
| Crates that depend on a listed crate directly | Not measured | No |
Corrections and review history
No correction applies to this entry.
Judgments
A judgment enters only through an approved issue and a merged pull request.
No judgment applies to this entry.