linux下4090D使用llama.cpp推理GGUF并对外提供访问接口
从0开始在ubuntu 下使用llama.cpp推理Qwen3.6-35B-A3B-UD-IQ4的GGUF模型。
最关键的点是下面这点代码。要按照自己的需求。自己测试修改调试,这个可以丢给AI帮你弄。
# 启动 llama-server 服务,所有参数行末添加注释
$SERVER_BIN \ # 执行 llama-server 可执行文件
-m "$MODEL_PATH" \ # 指定模型文件路径(GGUF 格式)
-c 262144 \ # 设置上下文长度为 262,144 tokens(模型最大支持)
-ngl 99 \ # 将 99 层(几乎所有层)加载到 GPU,充分利用显存
-t 8 \ # 使用 8 个 CPU 线程辅助推理(用于部分 CPU 计算)
--host 0.0.0.0 \ # 监听所有网络接口,允许局域网其他设备访问
--port $PORT \ # 监听端口(变量 $PORT,通常为 8080)
--cache-type-k q4_0 \ # KV Cache 的 K 使用 4-bit 量化,压缩显存占用
--cache-type-v q4_0 \ # KV Cache 的 V 使用 4-bit 量化,进一步节省显存
--flash-attn on \ # 启用 Flash Attention,加速注意力计算,必须配合非 FP16 KV Cache
--no-mmap \ # 禁用内存映射,强制一次性将模型载入 RAM,避免推理时的磁盘 I/O 延迟
--parallel 1 # 限制推理槽位为 1(单并发),最大化单请求吞吐量,减少显存占用 强制只使用 1 个槽位
一、安装CUDA Toolkit
了解你的系统版本
我们先用几个命令来确认你的Ubuntu版本和硬件信息,这样能选择最合适的安装方式。
# 查看发行版信息
lsb_release -a
# 或者
cat /etc/os-release
# 查看内核版本
uname -a
# 查看NVIDIA驱动版本和CUDA兼容性
nvidia-smi
比如我的:系统是 Ubuntu 24.04 LTS,NVIDIA 驱动版本 595.71.05,驱动支持的最高 CUDA 版本是 13.2
1.1 下载并安装 CUDA 软件源
我换了个目录。去到了Download去了。执行以下命令(这是针对 Ubuntu 24.04 的官方安装包):
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt-get update
完成这三步后,就可以继续安装 CUDA Toolkit 了:
# 4. 安装 CUDA Toolkit (我安装的 12.8 版本)
sudo apt-get -y install cuda-toolkit-12-8
安装完 CUDA Toolkit 后,请执行:
检查目录是否存在:
ls -l /usr/local/cuda
//应该会看到指向 /usr/local/cuda-12.8 的软链接
//lrwxrwxrwx 1 root root 22 6月 24 18:17 /usr/local/cuda -> /etc/alternatives/cuda
配置环境变量
echo 'export PATH=/usr/local/cuda/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc
验证
nvcc --version
//输出类似于
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2025 NVIDIA Corporation
Built on Fri_Feb_21_20:23:50_PST_2025
Cuda compilation tools, release 12.8, V12.8.93
Build cuda_12.8.r12.8/compiler.35583870_0
下一步:编译 llama.cpp(启用 CUDA)
# 进入 llama.cpp 目录
cd ~/Codes/llama.cpp
# 清理旧构建(如果有)
rm -rf build
# 使用 CMake 配置,启用 CUDA
cmake -B build -DGGML_CUDA=ON
//如果 cmake 配置顺利,会看到类似 "Configuring done" 和 "Generating done" 的提示。然后进行编译:
# 编译(利用所有 CPU 核心)
# 编译过程大约需要 3~5 分钟(取决于你的 CPU 性能)。完成后,检查 build/bin/server 是否存在
cmake --build build --config Release -j $(nproc)
# 应该会看到一个可执行文件(绿色高亮)。
ls -lh build/bin/llama-server
开启防火墙(我使用的是8080端口)
sudo ufw allow 8080/tcp
//提示成功
//Rule added
//Rule added (v6)
//执行防火墙检查
sudo ufw status
//输出内容
//Status: active
//To Action From
//-- ------ ----
//22/tcp ALLOW Anywhere
//8080/tcp ALLOW Anywhere
//22/tcp (v6) ALLOW Anywhere (v6)
//8080/tcp (v6) ALLOW Anywhere (v6)
编写脚本启动本地推理服务
#!/bin/bash
# ========================================
# 启动脚本:llama-server 服务管理
# ========================================
set -e
# ---------- 配置 ----------
PORT=8080
LLAMA_DIR="$HOME/Codes/llama.cpp"
MODEL_PATH="$LLAMA_DIR/models/Qwen3.6-35B-A3B-UD-IQ4_NL_XL.gguf"
SERVER_BIN="$LLAMA_DIR/build/bin/llama-server"
# ---------- 颜色 ----------
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${GREEN}=== 脚本目录结构 ===${NC}"
ls -lh "$(dirname "$0")"
echo -e "${GREEN}=== llama.cpp 目录结构 ===${NC}"
ls -lh "$LLAMA_DIR" | head -20
echo -e "${GREEN}=== 模型目录结构 ===${NC}"
ls -lh "$LLAMA_DIR/models"/*.gguf 2>/dev/null || echo "没有找到 .gguf 模型文件"
# ---------- 检查端口 ----------
echo -e "${YELLOW}检查端口 $PORT 是否被占用...${NC}"
if ss -lnt | grep -q ":$PORT "; then
# 端口被占用,尝试获取PID
if command -v fuser &>/dev/null; then
PID=$(fuser $PORT/tcp 2>/dev/null | awk '{print $2}')
elif command -v lsof &>/dev/null; then
PID=$(lsof -ti :$PORT 2>/dev/null)
else
PID=$(ss -tulnp 2>/dev/null | grep ":$PORT " | grep -oP 'pid=\K[0-9]+' | head -1)
fi
if [ -z "$PID" ]; then
echo -e "${RED}端口 $PORT 被占用,但无法获取 PID,请手动检查。${NC}"
exit 1
fi
PROC_NAME=$(ps -p $PID -o comm= 2>/dev/null || echo "未知进程")
echo -e "${YELLOW}发现进程 PID=$PID, 名称=$PROC_NAME 正在监听端口 $PORT${NC}"
if [[ "$PROC_NAME" == *"llama-server"* ]]; then
echo -e "${YELLOW}检测到旧的 llama-server 进程,正在终止...${NC}"
kill -9 $PID 2>/dev/null && echo -e "${GREEN}进程 $PID 已终止。${NC}" || { echo -e "${RED}终止失败,请检查权限。${NC}"; exit 1; }
sleep 2
else
echo -e "${RED}端口 $PORT 被其他进程占用($PROC_NAME,PID=$PID),无法继续。${NC}"
exit 1
fi
else
echo -e "${GREEN}端口 $PORT 空闲。${NC}"
fi
# ---------- 检查文件 ----------
if [ ! -f "$MODEL_PATH" ]; then
echo -e "${RED}模型文件不存在: $MODEL_PATH${NC}"
exit 1
fi
echo -e "${GREEN}模型文件存在: $MODEL_PATH${NC}"
if [ ! -x "$SERVER_BIN" ]; then
echo -e "${RED}可执行文件不存在或无权限: $SERVER_BIN${NC}"
exit 1
fi
echo -e "${GREEN}可执行文件存在: $SERVER_BIN${NC}"
# ---------- 启动服务 ----------
echo -e "${GREEN}启动 llama-server...${NC}"
cd "$LLAMA_DIR"
$SERVER_BIN \
-m "$MODEL_PATH" \
-c 262144 \
-ngl 99 \
-t 8 \
--host 0.0.0.0 \
--port $PORT \
--cache-type-k q4_0 \
--cache-type-v q4_0 \
--flash-attn on \
--no-mmap \
--parallel 1 # 强制只使用 1 个槽位
echo -e "${YELLOW}服务已停止。${NC}"
KV Cache 可选量化类型全解析
下表汇总了主要的 KV Cache 量化类型,并按“位宽”和“量化方法”进行了分类
| 分类 | 类型 | 说明 & 特点 |
|---|---|---|
| 高精度 (未量化) | F16, BF16, F32 |
默认选项,精度最高,显存占用也最大 |
| 8-bit 量化 | Q8_0 |
精度与显存的良好平衡点。相比 F16,显存占用减半,精度损失很小 |
Q8_1 |
另一种 8-bit 量化方式 | |
| 4/5/6-bit 量化 | Q4_0 |
显存占用仅为 F16 的 1/4,能最大程度节省显存,适合超长上下文 |
Q4_1, Q5_0, Q5_1, Q6_K |
在 4-6 bit 范围内提供不同精度和速度的选项 | |
| K-quant 系列 | Q2_K, Q3_K, Q4_K, Q5_K, Q8_K |
一种更先进的量化方法,在相同位宽下通常比非K-quant类型表现更好 |
| 重要性加权 (IQ) 系列 | IQ1_S, IQ2_XXS, IQ3_XXS, IQ4_XS, IQ4_NL 等 |
更聪明的量化方法,会根据数据重要性分配位数,在低位宽下能保留更好的效果 |
| 整数类型 | I8, I16, I32, I64 |
有符号整数类型 |
启动脚本
~/Codes/llama-scripts/start_llama_server.sh
如果没有报错,看到这样的消息就是成功了
0.11.118.951 I srv init: init: chat template, thinking = 1
0.11.119.083 I srv llama_server: model loaded
0.11.119.147 I srv llama_server: server is listening on http://0.0.0.0:8080
0.11.119.217 I srv update_slots: all slots are idle
这里看到speculative decoding will use checkpoints0.10.232.663 W common_speculative_init: no implementations specified for speculative decoding
还可以配置草稿模型。但是还没弄。
先往下
windows下写了一个测试脚本 名字叫做.\test_llama.ps1
# Test llama-server inference script
# Target server: http://192.168.1.109:8080
$serverUrl = "http://192.168.1.109:8080/v1/completions"
$prompt = "Hello, please introduce yourself in Chinese."
$maxTokens = 100
$temperature = 0.7
$body = @{
prompt = $prompt
max_tokens = $maxTokens
temperature = $temperature
} | ConvertTo-Json
Write-Host "Sending request to $serverUrl ..." -ForegroundColor Green
try {
$response = Invoke-RestMethod -Uri $serverUrl -Method Post -ContentType "application/json" -Body $body
if ($response.choices) {
$generatedText = $response.choices[0].text
} elseif ($response.content) {
$generatedText = $response.content
} else {
$generatedText = $response | ConvertTo-Json -Depth 3
}
Write-Host "Generated text:" -ForegroundColor Yellow
Write-Host $generatedText
} catch {
Write-Host "Request failed:" $_.Exception.Message -ForegroundColor Red
Write-Host "Status code:" $_.Exception.Response.StatusCode.value__
}
运行后查看结果
PS D:\Codes> .\test_llama.ps1
Sending request to http://192.168.1.109:8080/v1/completions ...
Generated text:
<think>
</think>
你好!我是通义千问(Qwen),是由阿里巴巴集团通义实验室独立研发的大语言模型。
很高兴为你提供帮助。我可以协助你完成各种任务,例如:
* **解答问题**:无论是常识查询、专业知识解析,还是复杂的逻辑推理。
* **内容创作**:撰写文章、故事、邮件、报告,或进行创意写作。
* **编程辅助**:编写代码、调试错误、解释代码
运行以下命令,确认显存和内存使用情况,按行执行:
nvidia-smi
free -h
ps aux | grep llama-server | grep -v grep
我的机器当前资源使用情况(推理后)
| 资源 | 占用 | 说明 |
|---|---|---|
| 显存(GPU) | 20.9 GB(总 24 GB) | 已充分利用,剩余 3.6 GB 作为安全余量,非常合理 |
| 内存(RAM) | 3.4 GB(总 62 GB) | 从之前的 ~20 GB 大幅下降,证明大部分模型层已从内存迁移至显存 |
| 推理速度 | 159.32 token/s(生成) | 已彻底摆脱 CPU 瓶颈,达到 GPU 极限性能| |
测试完毕后配置成开机自启动:
方案一:创建精简启动脚本 + Systemd 服务(推荐)
1. 创建精简启动脚本
新建一个文件 ~/Codes/llama-scripts/start_llama_server_daemon.sh:
#!/bin/bash
cd /home/duwenlong/Codes/llama.cpp
exec /home/duwenlong/Codes/llama.cpp/build/bin/llama-server \
-m /home/duwenlong/Codes/llama.cpp/models/Qwen3.6-35B-A3B-UD-IQ4_NL_XL.gguf \
-c 262144 \
-ngl 99 \
-t 8 \
--host 0.0.0.0 \
--port 8080 \
--cache-type-k q4_0 \
--cache-type-v q4_0 \
--flash-attn on \
--no-mmap \
--parallel 1
赋予执行权限:
chmod +x ~/Codes/llama-scripts/start_llama_server_daemon.sh
2. 创建 Systemd 服务文件
sudo nano /etc/systemd/system/llama-server.service
3. 重新启动服务
sudo systemctl daemon-reload
sudo systemctl start llama-server
sudo systemctl status llama-server
4. 验证与日志查看
如果服务成功启动,status 会显示 active (running)。你也可以实时查看日志确认模型加载:
sudo journalctl -u llama-server -f
//运行windows 下的脚本
PS D:\Codes> .\test_llama.ps1 //查看结果
验证开机自启:
重启 Linux(sudo reboot),然后重新登录,检查服务是否自动启动:
sudo systemctl status llama-server
浙公网安备 33010602011771号