Ubuntu + V100 环境下 llama.cpp 实践:环境准备与 CUDA 编译
本文记录在学校 HPC 服务器上,从基础环境准备到成功编译 NVIDIA Tesla V100 CUDA 版llama.cpp的完整过程。本文只保留实际执行步骤,不记录中间报错排查过程。
当前实践环境:
- 操作系统:Ubuntu
- 调度系统:Slurm
- GPU:NVIDIA Tesla V100-PCIE-32GB
- CUDA Toolkit:12.4
- Python:3.11
- Conda 环境:
llm - 工作目录:
/slurm/home/zhengjie/xss_llm - CMake:4.4.3
- llama.cpp 提交:
0ee9435
后续将在此基础上继续完成:
Qwen2.5-7B-Instruct ↓ GGUF ↓ 量化 ↓ llama.cpp 推理 ↓ llama-server 部署 ↓ 性能测试一、前期环境准备
1.1 创建项目目录
所有模型、数据、脚本、日志和实验结果统一放在:
/slurm/home/zhengjie/xss_llm创建基础目录:
cd/slurm/home/zhengjie/xss_llmmkdir-pmodelsmkdir-pdatasetsmkdir-pscriptsmkdir-plogsmkdir-poutputsmkdir-pcheckpoints目录结构:
xss_llm/ ├── checkpoints/ ├── datasets/ ├── logs/ ├── models/ ├── outputs/ └── scripts/1.2 创建 Conda 独立环境
创建llm环境:
conda create-nllmpython=3.11-y激活环境:
conda activate llm检查 Python:
python--versionwhichpython当前环境:
Python 3.11.16 /slurm/home/zhengjie/.conda/envs/llm/bin/python为了避免用户目录中的旧 Python 包影响当前环境,后续统一执行:
exportPYTHONNOUSERSITE=11.3 安装 PyTorch CUDA 版本
安装 PyTorch 2.6.0 + CUDA 12.4:
python-s-mpipinstall--no-cache-dir\torch==2.6.0\--index-url https://download.pytorch.org/whl/cu124验证:
python-s-<<'PY' import torch print("PyTorch:", torch.__version__) print("CUDA runtime:", torch.version.cuda) print("PyTorch path:", torch.__file__) print("CUDA available:", torch.cuda.is_available()) PY当前结果:
PyTorch: 2.6.0+cu124 CUDA runtime: 12.4 CUDA available: True1.4 安装大模型基础依赖
安装 Transformers、Accelerate 和 Hugging Face 相关依赖:
python-s-mpipinstall--no-cache-dir\transformers\accelerate\huggingface_hub\safetensors\sentencepiece\protobuf当前主要版本:
transformers 5.17.0 accelerate 1.15.0 huggingface-hub 1.32.0 safetensors 0.8.0 sentencepiece 0.2.2 protobuf 7.36.21.5 验证 V100 GPU 与 FP16 计算
进入已经申请到 GPU 的计算环境后执行:
nvidia-smi当前 GPU:
Tesla V100-PCIE-32GB检查 PyTorch 是否能够正常访问 GPU:
python-s-<<'PY' import torch print("CUDA available:", torch.cuda.is_available()) print("GPU:", torch.cuda.get_device_name(0)) print("计算能力:", torch.cuda.get_device_capability(0)) PY当前结果:
CUDA available: True GPU: Tesla V100-PCIE-32GB 计算能力: (7, 0)V100 的 CUDA Compute Capability 为7.0,后续编译llama.cpp时对应 CUDA 架构:
sm_70验证 FP16 GPU 矩阵乘法:
python-s-<<'PY' import torch a = torch.tensor( [[1., 2.], [3., 4.]], device="cuda", dtype=torch.float16 ) b = torch.tensor( [[5., 6.], [7., 8.]], device="cuda", dtype=torch.float16 ) c = a @ b print(c) print("设备:", c.device) print("类型:", c.dtype) PY输出:
tensor([[19., 22.], [43., 50.]], device='cuda:0', dtype=torch.float16) 设备: cuda:0 类型: torch.float16至此,PyTorch + V100 + FP16 环境验证完成。
1.6 安装 CMake
在llm环境中安装:
conda activate llm condainstall-cconda-forge cmake-y检查版本:
cmake--version当前版本:
cmake version 4.4.31.7 加载 CUDA Toolkit 12.4
学校集群通过module提供 CUDA Toolkit。
查看可用 CUDA:
module avail cuda可用版本:
cuda/11.8 cuda/12.4加载 CUDA 12.4:
module load cuda/12.4检查 CUDA 编译器:
whichnvcc nvcc--version当前路径:
/slurm/software/compiler/nvidia/cuda/12.4/bin/nvcc版本:
Cuda compilation tools, release 12.4, V12.4.99二、下载并编译 llama.cpp
2.1 克隆 llama.cpp 源码
进入项目目录:
cd/slurm/home/zhengjie/xss_llm克隆:
gitclone https://github.com/ggml-org/llama.cpp.git进入源码目录:
cdllama.cpp查看当前提交:
gitrev-parse--shortHEAD本次实践使用:
0ee9435后续做性能测试时建议始终记录llama.cpp的提交编号,因为不同版本的参数、功能和性能可能发生变化。
2.2 编译前加载环境
conda activate llmexportPYTHONNOUSERSITE=1module load cuda/12.4检查:
whichnvcc nvcc--versioncmake--version本次环境:
NVCC: /slurm/software/compiler/nvidia/cuda/12.4/bin/nvcc CUDA: 12.4 CMake: 4.4.32.3 针对 V100 配置 CUDA 构建
进入源码目录:
cd/slurm/home/zhengjie/xss_llm/llama.cpp使用独立的build-v100构建目录,并针对 V100 的sm_70架构配置:
cmake-S.-Bbuild-v100\-DCMAKE_BUILD_TYPE=Release\-DGGML_CUDA=ON\-DCMAKE_CUDA_ARCHITECTURES=70\-DCMAKE_CUDA_COMPILER="$(command-vnvcc)"参数说明:
| 参数 | 作用 |
|---|---|
-S . | 指定当前目录为源码目录 |
-B build-v100 | 指定独立构建目录 |
CMAKE_BUILD_TYPE=Release | 使用 Release 优化构建 |
GGML_CUDA=ON | 启用 CUDA 后端 |
CMAKE_CUDA_ARCHITECTURES=70 | 针对 Tesla V100 编译 |
CMAKE_CUDA_COMPILER | 指定 CUDA 12.4 的nvcc |
配置完成后:
Configuring done (8.3s) Generating done (2.0s)2.4 编译四个主要程序
使用 4 个 CPU 核心并行编译:
cmake--buildbuild-v100\--configRelease\--targetllama-cli llama-quantize llama-server llama-bench\-j4四个程序的用途:
| 程序 | 用途 |
|---|---|
llama-cli | 命令行模型推理 |
llama-quantize | GGUF 模型量化 |
llama-server | HTTP 推理服务 |
llama-bench | 推理性能测试 |
CUDA 核心模板与底层 CUDA 算子的编译是整个过程最耗时的部分,完成后最后的链接阶段会明显更快。
最终四个目标均成功构建。
2.5 检查生成的二进制文件
ls-lh\build-v100/bin/llama-cli\build-v100/bin/llama-quantize\build-v100/bin/llama-server\build-v100/bin/llama-bench实际结果:
-rwxrwxr-x 1 zhengjie zhengjie 18K Sep 22 16:28 build-v100/bin/llama-bench -rwxrwxr-x 1 zhengjie zhengjie 1.4M Sep 22 16:27 build-v100/bin/llama-cli -rwxrwxr-x 1 zhengjie zhengjie 18K Sep 22 16:27 build-v100/bin/llama-quantize -rwxrwxr-x 1 zhengjie zhengjie 18K Sep 22 16:28 build-v100/bin/llama-server2.6 检查 CUDA 动态链接
执行:
ldd build-v100/bin/llama-cli|grep-E"ggml-cuda|cudart|cublas"可以看到:
libggml-cuda.so.0 libcudart.so.12 libcublas.so.12 libcublasLt.so.12说明当前llama.cpp已成功启用 CUDA 后端,并正确链接 CUDA 12 运行时与 cuBLAS。
2.7 检查 llama-cli 版本
执行:
./build-v100/bin/llama-cli--version输出:
version: 0.4.1-dev (build 1, commit 0ee9435) built with GNU 11.4.0 for Linux x86_64查看帮助:
./build-v100/bin/llama-cli--help|head-35常用参数包括:
-t, --threads N -c, --ctx-size N -n, --predict N -b, --batch-size N -ub, --ubatch-size N至此,针对 NVIDIA Tesla V100(sm_70)编译的 CUDA 版本llama.cpp已准备完成。
三、针对 V100 编译 CUDA 版 llama.cpp
3.1 实践环境与编译目标
本次实验采用学校 Ubuntu HPC 服务器,使用已创建的llmConda 环境。GPU 为 NVIDIA Tesla V100-PCIE-32GB,其 CUDA Compute Capability 为7.0,对应的 CUDA 架构为sm_70。
| 项目 | 本次配置 |
|---|---|
| 工作目录 | /slurm/home/zhengjie/xss_llm |
| Conda 环境 | llm |
| CUDA Toolkit | 12.4 |
| CMake | 4.4.3 |
| C++ 编译器 | GNU 11.4.0 |
| llama.cpp 提交 | 0ee9435 |
| 编译目标 | llama-cli、llama-quantize、llama-server、llama-bench |
这里要区分两个概念:PyTorch 能调用 CUDA,不等于具备编译 CUDA 源码所需的nvcc。编译 llama.cpp 的 CUDA 后端时,我们使用学校提供的 CUDA Toolkit 12.4。
3.2 加载 CUDA Toolkit
在学校允许的计算任务环境中执行编译;GPU 推理则必须在已经分配到 GPU 的任务中进行。
conda activate llmexportPYTHONNOUSERSITE=1module load cuda/12.4cd/slurm/home/zhengjie/xss_llmwhichnvcc nvcc--versioncmake--version实际工具信息:
/slurm/software/compiler/nvidia/cuda/12.4/bin/nvcc Cuda compilation tools, release 12.4, V12.4.99 cmake version 4.4.33.3 获取源码并固定版本
cd/slurm/home/zhengjie/xss_llmgitclone https://github.com/ggml-org/llama.cpp.gitcdllama.cppgitrev-parse--shortHEAD本次实际使用的提交为:
0ee9435如果本地已经存在
llama.cpp/,直接进入原目录即可,不要重复克隆。做性能实验时要记录提交号,避免把不同版本的结果直接混在一起。
3.4 用 CMake 配置 V100 CUDA 后端
cd/slurm/home/zhengjie/xss_llm/llama.cpp cmake-S.-Bbuild-v100\-DCMAKE_BUILD_TYPE=Release\-DGGML_CUDA=ON\-DCMAKE_CUDA_ARCHITECTURES=70\-DCMAKE_CUDA_COMPILER="$(command-vnvcc)"| 选项 | 含义 |
|---|---|
-B build-v100 | 使用独立构建目录,不与其他配置混用 |
Release | 启用面向运行的优化构建 |
GGML_CUDA=ON | 启用 llama.cpp 的 CUDA 后端 |
CMAKE_CUDA_ARCHITECTURES=70 | 针对 V100 的sm_70架构构建 |
CMAKE_CUDA_COMPILER | 使用 CUDA 12.4 模块中的nvcc |
本次配置已完成Configuring done和Generating done。
3.5 编译四个主程序
按已申请的 4 个 CPU 核心设置并行数:
cmake--buildbuild-v100\--configRelease\--targetllama-cli llama-quantize llama-server llama-bench\-j4| 程序 | 用途 |
|---|---|
llama-cli | 命令行模型推理 |
llama-quantize | 将 GGUF 权重量化为指定类型 |
llama-server | 启动 HTTP 推理服务 |
llama-bench | 对模型的输入处理与生成性能做基准测试 |
本次四个目标程序全部编译成功。
3.6 验证编译结果
查看文件:
ls-lh\build-v100/bin/llama-cli\build-v100/bin/llama-quantize\build-v100/bin/llama-server\build-v100/bin/llama-bench查看版本:
./build-v100/bin/llama-cli--version实际输出:
version: 0.4.1-dev (build 1, commit 0ee9435) built with GNU 11.4.0 for Linux x86_64检查 CUDA 动态库链接:
ldd build-v100/bin/llama-cli|grep-E'ggml-cuda|cudart|cublas'本次输出包含:
libggml-cuda.so.0 libcudart.so.12 libcublas.so.12 libcublasLt.so.12这说明程序成功链接 CUDA 后端及 CUDA 相关运行库。实际推理是否把层卸载到 GPU,还应结合 GPU 可见性和运行日志另行确认。
四、Qwen2.5-7B GGUF 下载与首次 llama.cpp 推理
4.1 明确模型、运行框架和硬件的分工
本次选择Qwen2.5-7B-Instruct,运行官方提供的Q4_K_MGGUF 量化权重。
| 对象 | 在实验中负责什么 |
|---|---|
| Qwen2.5-7B-Instruct | 已训练好的模型及其权重,负责生成回答 |
| GGUF | 保存模型权重、模型参数与分词器等信息的文件格式 |
| Q4_K_M | 模型权重所采用的量化类型 |
| llama.cpp | 加载 GGUF 并执行推理的程序与相关工具 |
| V100 | 进行计算的硬件 |
需要特别说明:本章使用的是官方已经量化好的 Q4_K_M 模型,还没有自行完成 FP16 → GGUF → Q4_K_M 量化。
4.2 下载官方 Q4_K_M 模型的两个分片
官方模型仓库:
https://huggingface.co/Qwen/Qwen2.5-7B-Instruct-GGUF
模型统一存放在:
/slurm/home/zhengjie/xss_llm/models/Qwen2.5-7B-Instruct-GGUF/先准备目录:
conda activate llmexportPYTHONNOUSERSITE=1cd/slurm/home/zhengjie/xss_llmmkdir-pmodels/Qwen2.5-7B-Instruct-GGUF使用 Hugging Face CLI 指定下载 Q4_K_M 的两个分片:
hf download Qwen/Qwen2.5-7B-Instruct-GGUF\qwen2.5-7b-instruct-q4_k_m-00001-of-00002.gguf\qwen2.5-7b-instruct-q4_k_m-00002-of-00002.gguf\--local-dir /slurm/home/zhengjie/xss_llm/models/Qwen2.5-7B-Instruct-GGUF本次实际下载采用了https://hf-mirror.com镜像源,两个分片均下载完成。上方保留的是标准下载命令;使用镜像时需按所在网络环境另行配置。
确认两个分片均存在:
ls-lh/slurm/home/zhengjie/xss_llm/models/Qwen2.5-7B-Instruct-GGUF/*.gguf| 文件 | 本次显示大小 |
|---|---|
qwen2.5-7b-instruct-q4_k_m-00001-of-00002.gguf | 约 3.8 GB |
qwen2.5-7b-instruct-q4_k_m-00002-of-00002.gguf | 约 658 MB |
两个分片共同组成同一个模型,不是两个可以分别使用的模型,也无需手工cat拼接。调用第一片时,llama.cpp 会读取后续分片。
4.3 Q4_K_M 究竟是什么意思?
Q4_K_M可以拆成:
- Q4:以约 4-bit 为基础的量化权重编码。
- K:llama.cpp 的 K 系列分块量化表示,包含分块所需的缩放等信息。
- M:Medium 变体;并非所有张量都严格使用统一的 4-bit 精度。
因此,它不是“把所有 FP16 数字直接裁成 4 位”。更准确的理解是:利用分块与混合精度表示,减少权重体积,同时尽量保留模型的生成能力。
还应区分GGUF和Q4_K_M:GGUF 是文件格式,Q4_K_M 是权重的量化类型。7B 表示参数规模约 70 亿,不是“7GB 模型”。
4.4 运行单轮中文推理
在已分配 V100 的 GPU 计算任务中执行:
conda activate llmexportPYTHONNOUSERSITE=1module load cuda/12.4cd/slurm/home/zhengjie/xss_llmMODEL="/slurm/home/zhengjie/xss_llm/models/Qwen2.5-7B-Instruct-GGUF/qwen2.5-7b-instruct-q4_k_m-00001-of-00002.gguf"./llama.cpp/build-v100/bin/llama-cli\-m"$MODEL"\-ngl99\-c2048\-t4\-n128\--temp0\--single-turn\-p"请用通俗易懂的语言解释什么是大语言模型,控制在100字以内。"常用参数:
| 参数 | 本次含义 |
|---|---|
-m | 指定第一片 GGUF 模型文件 |
-ngl 99 | 尽可能将模型层卸载到 GPU;实际层数以日志为准 |
-c 2048 | 上下文大小 2048 Token |
-t 4 | 使用 4 个 CPU 线程 |
-n 128 | 最多生成 128 个 Token |
--temp 0 | 使用确定性较强的贪心式生成设置 |
--single-turn | 回答单轮后退出,便于脚本化测试 |
-p | 输入问题 |
本次运行使用源码提交0ee9435,不要照搬旧版llama.cpp的交互参数。
4.5 首次推理结果
本次模型已经成功生成中文回答,并在回答一轮后退出。
实际回答:
大语言模型是一种人工智能模型,能理解和生成人类般的文字内容,像聊天、写文章一样,非常智能灵活。它经过大量数据训练,能回答问题、创作文字,还能不断学习进步。
三次运行的速度记录:
| 次数 | Prompt 处理速度 | Generation 生成速度 |
|---|---|---|
| 第 1 次 | 507.5 tokens/s | 76.8 tokens/s |
| 第 2 次 | 710.6 tokens/s | 78.5 tokens/s |
| 第 3 次 | 711.5 tokens/s | 78.1 tokens/s |
其中:
- Prompt processing:处理已经给定的输入 Token。
- Generation:模型逐步生成新的 Token;
tokens/s不等于“汉字数/秒”。
这三次数据是短问题的首次运行记录,尚不能替代固定输入长度和生成长度的正式基准测试。
4.6 保存实验日志
mkdir-p/slurm/home/zhengjie/xss_llm/logs ./llama.cpp/build-v100/bin/llama-cli\-m"$MODEL"\-ngl99\-c2048\-t4\-n128\--temp0\--single-turn\-p"请用通俗易懂的语言解释什么是大语言模型,控制在100字以内。"\2>&1|tee/slurm/home/zhengjie/xss_llm/logs/qwen2.5-7b-q4km-first-run.logtee会同时显示终端输出并保存日志,便于后续写博客、检查参数和比较实验。
4.7 本章小结与后续实践
至此已经完成:
V100 CUDA 编译环境 ↓ llama.cpp 四个程序成功编译 ↓ 下载官方 Qwen2.5-7B Q4_K_M GGUF(两个分片) ↓ llama-cli 单轮中文推理 ↓ 记录 Prompt 和 Generation 速度下一步将使用llama-bench建立固定条件的Q4_K_M 性能基线,然后再下载高精度模型、转换 GGUF、自己量化并比较不同格式。最终通过llama-server完成推理服务部署。