一个独立的 Python/C++/CUDA 实现,用于运行 4 位 GPTQ 权重的 Llama 模型,旨在现代 GPU 上实现快速且内存高效。
免责声明:项目正在推进中,但仍处于开发阶段!
我主要在 RTX 4090 和 RTX 3090-Ti 上进行开发。30 系列及之后的 NVIDIA GPU 应能得到良好支持,但任何 Pascal 或更早、FP16 支持较差的 GPU 性能可能不佳。对于旧款 GPU,目前 AutoGPTQ 或 GPTQ-for-LLaMa 是更好的选择。理论上也支持 ROCm(通过 HIP),但目前没有 AMD 设备进行测试或优化。
torch 已在 cu118 上的 2.0.1 和 2.1.0(nightly)版本测试safetensors 0.3.2sentencepieceninja仅针对 Web UI 的额外依赖:
flaskwaitresspip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cu118
要在 Windows(无需 WSL)上运行:
Visual Studio 2022 IDE,或者仅安装 Build Tools for Visual Studio 2022 包(确保在安装程序中勾选 Desktop development with C++),具体选择哪个并不重要。克隆仓库,安装依赖,并运行基准测试:
git clone https://github.com/turboderp/exllama
cd exllama
pip install -r requirements.txt
python test_benchmark_inference.py -d <模型文件路径> -p -ppl
CUDA 扩展在运行时加载,因此无需单独安装。它将在首次运行时编译并缓存到 ~/.cache/torch_extensions/,这可能需要一点时间。如果一开始没有反应,请稍等片刻让它编译。
聊天机器人示例:
python example_chatbot.py -d <模型文件路径> -un "Jeff" -p prompt_chatbort.txt
jllllll 目前维护了一个可安装的 Python 模块 here,可能更适合将 ExLlama 集成到其他项目中。
我还为它制作了一个简单的 Web UI。别看 JavaScript 代码,它主要是由 ChatGPT 编写的,可能会让你做噩梦。但它基本能用,而且挺有趣的,尤其是多机器人模式:

运行方法:
pip install -r requirements-web.txt
python webui/app.py -d <模型文件路径>
请注意,会话默认存储在 ~/exllama_sessions/。如果需要,可以使用 -sd 更改该位置。
为了安全优势和更轻松的部署,也可以在隔离的 docker 容器中运行 Web UI。注意:docker 镜像目前仅支持 NVIDIA GPU。
建议在 rootless 模式 下运行 docker。
构建 docker 镜像最简单的方法是使用 docker compose。首先,在 .env 文件中将 MODEL_PATH 和 SESSIONS_PATH 变量设置为宿主机上的实际目录。然后运行:
docker compose build
也可以手动构建镜像:
docker build -t exllama-web .
注意:默认情况下,docker 容器内的服务由非 root 用户运行。因此,在容器入口点(entrypoint.sh)中,绑定挂载目录(默认 docker-compose.yml 文件中的 /data/model 和 /data/exllama_sessions)的所有权会更改为此非 root 用户。要禁用此功能,如果使用 docker compose,请在 .env 文件中设置 RUN_UID=0;如果手动构建镜像,请使用以下命令:
docker build -t exllama-web --build-arg RUN_UID=0 .
使用 docker compose:
docker compose up
现在可以在宿主机上通过 http://localhost:5000 访问 Web UI。
配置可以在 docker-compose.yml 中查看,并通过创建 docker-compose.override.yml 文件进行更改。
手动运行:
docker run --gpus all -p 5000:5000 -v <模型目录路径>:/data/model/ -v <会话目录路径>:/data/exllama_sessions --rm -it exllama-web --host 0.0.0.0:5000
| 模型 | 大小 | 分组大小 | 激活 | 序列长度 | VRAM | 提示速度 | 最佳速度 | 最差速度 | 困惑度 |
|---|---|---|---|---|---|---|---|---|---|
| Llama | 7B | 128 | 否 | 2,048 词元 | 5,194 MB | 13,918 t/s | 173 t/s | 140 t/s | 6.45 |
| Llama | 13B | 128 | 否 | 2,048 词元 | 9,127 MB | 7,507 t/s | 102 t/s | 86 t/s | 5.60 |
| Llama | 33B | 128 | 否 | 2,048 词元 | 20,795 MB | 2,959 t/s | 47 t/s | 40 t/s | 4.60 |
| Llama | 33B | 128 | 是 | 2,048 词元 | 20,795 MB | 2,784 t/s | 45 t/s | 37 t/s | 4.55 |
| Llama | 33B | 32 | 是 | 1,550 词元 1 | 21,486 MB | 2,636 t/s | 41 t/s | 37 t/s | 4.52 |
| Koala | 13B | 128 | 是 | 2,048 词元 | 9,127 MB | 5,529 t/s | 93 t/s | 79 t/s | 6.73 |
| WizardLM | 33B | - | 是 | 2,048 词元 | 20,199 MB | 2,313 t/s | 47 t/s | 40 t/s | 5.75 |
| OpenLlama | 3B | 128 | 是 | 2,048 词元 | 3,128 MB | 16,419 t/s | 226 t/s | 170 t/s | 7.81 |
1 无法在不超出内存的情况下达到完整序列长度
所有测试均在标准 RTX 4090 / 12900K 上完成,运行桌面环境,同时有其他几个应用程序也在使用 VRAM。
"提示" 速度是在列出的序列长度减去 128 个词元上进行推理的速度。"最差" 是完整上下文最后 128 个词元的平均速度(最坏情况),"最佳" 列出的是空序列中前 128 个词元的速度(最佳情况)。
VRAM 使用情况由 PyTorch 报告,不包括 PyTorch 自身的开销(CUDA 内核、内部缓冲区等)。这本身有些不可预测。最好的办法是仅优化模型使用的 VRAM,可能在 24 GB GPU 上瞄准 20 GB,以确保有空间容纳桌面环境和 Torch 的所有内部组件。
困惑度测量仅用于验证模型是否正常工作。使用的数据集是来自 WikiText 的一个特定小样本,因此分数无法与其他 Llama 基准测试比较,仅用于比较不同的 Llama 模型。
以下基准测试来自 4090 + 3090-Ti,使用 -gs 17.2,24:
| 模型 | 大小 | 分组大小 | 激活 | 序列长度 | VRAM | 提示速度 | 最佳速度 | 最差速度 | 困惑度 |
|---|---|---|---|---|---|---|---|---|---|
| Llama | 65B | 128 | 是 | 2,048 词元 | 39,804 MB | 1,109 t/s | 20 t/s | 18 t/s | 4.20 |
| Llama | 65B | 32 | 是 | 2,048 词元 | 43,424 MB | 1,037 t/s | 17 t/s | 16 t/s | 4.11 |
| Llama-2 | 70B | 128 | 是 | 2,048 词元 | 40,680 MB | 914 t/s | 17 t/s | 14 t/s | 4.15 |
| Llama-2 | 70B | 32 | 是 | 2,048 词元 | 36,815 MB | 874 t/s | 15 t/s | 12 t/s | 4.10 |
请注意,由于 Llama 和 Llama 2 的预训练数据集不同,它们的困惑度分数可能不完全具有可比性。
待办事项列表已移至 此处。
此处 是目前确认可用的模型列表。
2023-01-09:添加了 rope_theta 参数以支持(至少部分)CodeLlama。如果你之前使用 alpha = 97 或类似设置,对于 CodeLlama 模型,你将不再需要它。关于扩展词汇表的问题仍有待解决。
2023-08-09:添加了对分片模型的支持。config.model_path 现在接受文件名或文件名列表。如果给定模型目录,model_init() 将检测多个 .safetensors 文件。请注意各种示例中的变化:model_path = glob.glob(st_pattern)[0] 变为简单的 model_path = glob.glob(st_pattern)。此外,util/shard.py 中有一个小脚本用于分割大的 .safetensors 文件。它还会为分片模型生成一个 index.json 文件,只是为了完整性,尽管 ExLlama 读取分片时不需要它。注意:safetensors 依赖已升级到版本 0.3.2。
2023-08-12:初步、初始且试探性地发布了 ExLlamaV2。它还没有实现 ExLlamaV1 的所有功能,但在其实现的功能上表现更好。所以去看看吧!