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 量化类型,并按“位宽”和“量化方法”进行了分类

分类 类型 说明 & 特点
高精度 (未量化) F16BF16F32 默认选项,精度最高,显存占用也最大
8-bit 量化 Q8_0 精度与显存的良好平衡点。相比 F16,显存占用减半,精度损失很小
Q8_1 另一种 8-bit 量化方式
4/5/6-bit 量化 Q4_0 显存占用仅为 F16 的 1/4,能最大程度节省显存,适合超长上下文
Q4_1Q5_0Q5_1Q6_K 在 4-6 bit 范围内提供不同精度和速度的选项
K-quant 系列 Q2_KQ3_KQ4_KQ5_KQ8_K 一种更先进的量化方法,在相同位宽下通常比非K-quant类型表现更好
重要性加权 (IQ) 系列 IQ1_SIQ2_XXSIQ3_XXSIQ4_XSIQ4_NL 等 更聪明的量化方法,会根据数据重要性分配位数,在低位宽下能保留更好的效果
整数类型 I8I16I32I64 有符号整数类型

启动脚本

~/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
posted @ 2026-06-24 23:36  杜文龙  阅读(64)  评论(0)    收藏  举报